@dxos/react-ui-editor 0.6.14-main.2b6a0f3 → 0.6.14-main.f49f251

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (101) hide show
  1. package/dist/lib/browser/index.mjs +650 -479
  2. package/dist/lib/browser/index.mjs.map +4 -4
  3. package/dist/lib/browser/meta.json +1 -1
  4. package/dist/lib/node/index.cjs +726 -545
  5. package/dist/lib/node/index.cjs.map +4 -4
  6. package/dist/lib/node/meta.json +1 -1
  7. package/dist/lib/node-esm/index.mjs +650 -478
  8. package/dist/lib/node-esm/index.mjs.map +4 -4
  9. package/dist/lib/node-esm/meta.json +1 -1
  10. package/dist/types/src/TextEditor.stories.d.ts.map +1 -1
  11. package/dist/types/src/extensions/automerge/cursor.d.ts +1 -1
  12. package/dist/types/src/extensions/automerge/cursor.d.ts.map +1 -1
  13. package/dist/types/src/extensions/comments.d.ts +1 -1
  14. package/dist/types/src/extensions/comments.d.ts.map +1 -1
  15. package/dist/types/src/extensions/factories.d.ts +1 -0
  16. package/dist/types/src/extensions/factories.d.ts.map +1 -1
  17. package/dist/types/src/extensions/focus.d.ts +7 -0
  18. package/dist/types/src/extensions/focus.d.ts.map +1 -0
  19. package/dist/types/src/extensions/index.d.ts +2 -0
  20. package/dist/types/src/extensions/index.d.ts.map +1 -1
  21. package/dist/types/src/extensions/markdown/image.d.ts +3 -6
  22. package/dist/types/src/extensions/markdown/image.d.ts.map +1 -1
  23. package/dist/types/src/extensions/selection.d.ts +24 -0
  24. package/dist/types/src/extensions/selection.d.ts.map +1 -0
  25. package/dist/types/src/hooks/useTextEditor.d.ts +1 -1
  26. package/dist/types/src/hooks/useTextEditor.d.ts.map +1 -1
  27. package/dist/types/src/index.d.ts +1 -1
  28. package/dist/types/src/types.d.ts.map +1 -0
  29. package/dist/types/src/{state → util}/cursor.d.ts +7 -1
  30. package/dist/types/src/util/cursor.d.ts.map +1 -0
  31. package/dist/types/src/{util.d.ts → util/debug.d.ts} +6 -2
  32. package/dist/types/src/util/debug.d.ts.map +1 -0
  33. package/dist/types/src/util/dom.d.ts.map +1 -0
  34. package/dist/types/src/{state/util.d.ts → util/facet.d.ts} +1 -1
  35. package/dist/types/src/util/facet.d.ts.map +1 -0
  36. package/dist/types/src/util/index.d.ts +6 -0
  37. package/dist/types/src/util/index.d.ts.map +1 -0
  38. package/dist/types/src/util/react.d.ts.map +1 -0
  39. package/package.json +28 -43
  40. package/src/TextEditor.stories.tsx +8 -6
  41. package/src/extensions/annotations.ts +1 -1
  42. package/src/extensions/automerge/automerge.ts +1 -1
  43. package/src/extensions/automerge/cursor.ts +1 -1
  44. package/src/extensions/awareness/awareness.ts +1 -1
  45. package/src/extensions/command/hint.ts +1 -1
  46. package/src/extensions/command/state.ts +1 -1
  47. package/src/extensions/comments.ts +3 -4
  48. package/src/extensions/factories.ts +5 -1
  49. package/src/extensions/focus.ts +35 -0
  50. package/src/extensions/folding.tsx +1 -1
  51. package/src/extensions/index.ts +2 -0
  52. package/src/extensions/markdown/decorate.ts +1 -1
  53. package/src/extensions/markdown/image.ts +53 -42
  54. package/src/extensions/modes.ts +1 -1
  55. package/src/{state/state.ts → extensions/selection.ts} +22 -22
  56. package/src/hooks/useTextEditor.ts +2 -3
  57. package/src/index.ts +1 -1
  58. package/src/{state → util}/cursor.ts +9 -3
  59. package/src/{util.ts → util/debug.ts} +15 -2
  60. package/src/{extensions/util → util}/index.ts +3 -2
  61. package/dist/lib/browser/chunk-CIQSMP7K.mjs +0 -148
  62. package/dist/lib/browser/chunk-CIQSMP7K.mjs.map +0 -7
  63. package/dist/lib/browser/state/index.mjs +0 -17
  64. package/dist/lib/browser/state/index.mjs.map +0 -7
  65. package/dist/lib/node/chunk-GZWIENFM.cjs +0 -169
  66. package/dist/lib/node/chunk-GZWIENFM.cjs.map +0 -7
  67. package/dist/lib/node/state/index.cjs +0 -39
  68. package/dist/lib/node/state/index.cjs.map +0 -7
  69. package/dist/lib/node-esm/chunk-GP5RCZ3X.mjs +0 -150
  70. package/dist/lib/node-esm/chunk-GP5RCZ3X.mjs.map +0 -7
  71. package/dist/lib/node-esm/state/index.mjs +0 -18
  72. package/dist/lib/node-esm/state/index.mjs.map +0 -7
  73. package/dist/types/src/extensions/util/dom.d.ts.map +0 -1
  74. package/dist/types/src/extensions/util/error.d.ts +0 -2
  75. package/dist/types/src/extensions/util/error.d.ts.map +0 -1
  76. package/dist/types/src/extensions/util/index.d.ts +0 -5
  77. package/dist/types/src/extensions/util/index.d.ts.map +0 -1
  78. package/dist/types/src/extensions/util/overlap.d.ts +0 -8
  79. package/dist/types/src/extensions/util/overlap.d.ts.map +0 -1
  80. package/dist/types/src/extensions/util/react.d.ts.map +0 -1
  81. package/dist/types/src/state/cursor.d.ts.map +0 -1
  82. package/dist/types/src/state/doc.d.ts +0 -5
  83. package/dist/types/src/state/doc.d.ts.map +0 -1
  84. package/dist/types/src/state/index.d.ts +0 -6
  85. package/dist/types/src/state/index.d.ts.map +0 -1
  86. package/dist/types/src/state/state.d.ts +0 -20
  87. package/dist/types/src/state/state.d.ts.map +0 -1
  88. package/dist/types/src/state/types.d.ts.map +0 -1
  89. package/dist/types/src/state/util.d.ts.map +0 -1
  90. package/dist/types/src/util.d.ts.map +0 -1
  91. package/src/extensions/util/error.ts +0 -15
  92. package/src/extensions/util/overlap.ts +0 -12
  93. package/src/state/doc.ts +0 -10
  94. package/src/state/index.ts +0 -11
  95. /package/dist/types/src/{state/types.d.ts → types.d.ts} +0 -0
  96. /package/dist/types/src/{extensions/util → util}/dom.d.ts +0 -0
  97. /package/dist/types/src/{extensions/util → util}/react.d.ts +0 -0
  98. /package/src/{state/types.ts → types.ts} +0 -0
  99. /package/src/{extensions/util → util}/dom.ts +0 -0
  100. /package/src/{state/util.ts → util/facet.ts} +0 -0
  101. /package/src/{extensions/util → util}/react.tsx +0 -0
@@ -1,12 +1,3 @@
1
- import {
2
- Cursor,
3
- createEditorStateTransaction,
4
- documentId,
5
- localStorageStateStoreAdapter,
6
- singleValueFacet,
7
- state
8
- } from "./chunk-CIQSMP7K.mjs";
9
-
10
1
  // packages/ui/react-ui-editor/src/translations.ts
11
2
  var translationKey = "react-ui-editor";
12
3
  var translations_default = [
@@ -43,7 +34,7 @@ var translations_default = [
43
34
  ];
44
35
 
45
36
  // packages/ui/react-ui-editor/src/index.ts
46
- import { keymap as keymap10 } from "@codemirror/view";
37
+ import { keymap as keymap11 } from "@codemirror/view";
47
38
  import { tags as tags2 } from "@lezer/highlight";
48
39
  import { TextKind } from "@dxos/protocols/proto/dxos/echo/model/text";
49
40
 
@@ -59,19 +50,176 @@ import { getSize } from "@dxos/react-ui-theme";
59
50
  import { StateField } from "@codemirror/state";
60
51
  import { Decoration, EditorView } from "@codemirror/view";
61
52
  import { isNotFalsy } from "@dxos/util";
53
+
54
+ // packages/ui/react-ui-editor/src/util/facet.ts
55
+ import { Facet } from "@codemirror/state";
56
+ var singleValueFacet = (defaultValue) => Facet.define({
57
+ // Called immediately.
58
+ combine: (providers) => {
59
+ return providers[0] ?? defaultValue;
60
+ }
61
+ });
62
+
63
+ // packages/ui/react-ui-editor/src/util/cursor.ts
64
+ var overlap = (a, b) => a.from <= b.to && a.to >= b.from;
65
+ var defaultCursorConverter = {
66
+ toCursor: (position) => position.toString(),
67
+ fromCursor: (cursor) => parseInt(cursor)
68
+ };
69
+ var Cursor = class _Cursor {
70
+ static {
71
+ this.converter = singleValueFacet(defaultCursorConverter);
72
+ }
73
+ static {
74
+ this.getCursorFromRange = (state, range) => {
75
+ const cursorConverter2 = state.facet(_Cursor.converter);
76
+ const from = cursorConverter2.toCursor(range.from);
77
+ const to = cursorConverter2.toCursor(range.to, -1);
78
+ return [
79
+ from,
80
+ to
81
+ ].join(":");
82
+ };
83
+ }
84
+ static {
85
+ this.getRangeFromCursor = (state, cursor) => {
86
+ const cursorConverter2 = state.facet(_Cursor.converter);
87
+ const parts = cursor.split(":");
88
+ const from = cursorConverter2.fromCursor(parts[0]);
89
+ const to = cursorConverter2.fromCursor(parts[1]);
90
+ return from !== void 0 && to !== void 0 ? {
91
+ from,
92
+ to
93
+ } : void 0;
94
+ };
95
+ }
96
+ };
97
+
98
+ // packages/ui/react-ui-editor/src/util/debug.ts
99
+ import { log } from "@dxos/log";
100
+ var __dxlog_file = "/home/runner/work/dxos/dxos/packages/ui/react-ui-editor/src/util/debug.ts";
101
+ var wrapWithCatch = (fn) => {
102
+ return (...args) => {
103
+ try {
104
+ return fn(...args);
105
+ } catch (err) {
106
+ log.catch(err, void 0, {
107
+ F: __dxlog_file,
108
+ L: 15,
109
+ S: void 0,
110
+ C: (f, a) => f(...a)
111
+ });
112
+ }
113
+ };
114
+ };
115
+ var callbackWrapper = (fn) => (...args) => {
116
+ try {
117
+ return fn(...args);
118
+ } catch (err) {
119
+ log.catch(err, void 0, {
120
+ F: __dxlog_file,
121
+ L: 29,
122
+ S: void 0,
123
+ C: (f, a) => f(...a)
124
+ });
125
+ }
126
+ };
127
+ var debugDispatcher = (trs, view) => {
128
+ logChanges(trs);
129
+ view.update(trs);
130
+ };
131
+ var logChanges = (trs) => {
132
+ const changes = trs.flatMap((tr) => {
133
+ if (tr.changes.empty) {
134
+ return void 0;
135
+ }
136
+ const changes2 = [];
137
+ tr.changes.iterChanges((fromA, toA, fromB, toB, inserted) => changes2.push(JSON.stringify({
138
+ fromA,
139
+ toA,
140
+ fromB,
141
+ toB,
142
+ inserted: inserted.toString()
143
+ })));
144
+ return changes2;
145
+ }).filter(Boolean);
146
+ if (changes.length) {
147
+ log.info("changes", {
148
+ changes
149
+ }, {
150
+ F: __dxlog_file,
151
+ L: 62,
152
+ S: void 0,
153
+ C: (f, a) => f(...a)
154
+ });
155
+ }
156
+ };
157
+
158
+ // packages/ui/react-ui-editor/src/util/dom.ts
159
+ var flattenRect = (rect, left) => {
160
+ const x = left ? rect.left : rect.right;
161
+ return {
162
+ left: x,
163
+ right: x,
164
+ top: rect.top,
165
+ bottom: rect.bottom
166
+ };
167
+ };
168
+ var scratchRange;
169
+ var textRange = (node, from, to = from) => {
170
+ const range = scratchRange || (scratchRange = document.createRange());
171
+ range.setEnd(node, to);
172
+ range.setStart(node, from);
173
+ return range;
174
+ };
175
+ var clientRectsFor = (dom) => {
176
+ if (dom.nodeType === 3) {
177
+ return textRange(dom, 0, dom.nodeValue.length).getClientRects();
178
+ } else if (dom.nodeType === 1) {
179
+ return dom.getClientRects();
180
+ } else {
181
+ return [];
182
+ }
183
+ };
184
+
185
+ // packages/ui/react-ui-editor/src/util/react.tsx
186
+ import React from "react";
187
+ import { createRoot } from "react-dom/client";
188
+ import { ThemeProvider } from "@dxos/react-ui";
189
+ import { defaultTx } from "@dxos/react-ui-theme";
190
+ var createElement = (tag, options, children) => {
191
+ const el = document.createElement(tag);
192
+ if (options?.className) {
193
+ el.className = options.className;
194
+ }
195
+ if (children) {
196
+ el.append(...Array.isArray(children) ? children : [
197
+ children
198
+ ]);
199
+ }
200
+ return el;
201
+ };
202
+ var renderRoot = (root, node) => {
203
+ createRoot(root).render(/* @__PURE__ */ React.createElement(ThemeProvider, {
204
+ tx: defaultTx
205
+ }, node));
206
+ return root;
207
+ };
208
+
209
+ // packages/ui/react-ui-editor/src/extensions/annotations.ts
62
210
  var annotationMark = Decoration.mark({
63
211
  class: "cm-annotation"
64
212
  });
65
213
  var annotations = (options = {}) => {
66
- const match = (state2) => {
214
+ const match = (state) => {
67
215
  const annotations2 = [];
68
- const text = state2.doc.toString();
216
+ const text = state.doc.toString();
69
217
  if (options.match) {
70
218
  const matches = text.matchAll(options.match);
71
219
  for (const match2 of matches) {
72
220
  const from = match2.index;
73
221
  const to = from + match2[0].length;
74
- const cursor = Cursor.getCursorFromRange(state2, {
222
+ const cursor = Cursor.getCursorFromRange(state, {
75
223
  from,
76
224
  to
77
225
  });
@@ -83,8 +231,8 @@ var annotations = (options = {}) => {
83
231
  return annotations2;
84
232
  };
85
233
  const annotationsState = StateField.define({
86
- create: (state2) => {
87
- return match(state2);
234
+ create: (state) => {
235
+ return match(state);
88
236
  },
89
237
  update: (value, tr) => {
90
238
  if (!tr.changes.empty) {
@@ -97,10 +245,10 @@ var annotations = (options = {}) => {
97
245
  annotationsState,
98
246
  EditorView.decorations.compute([
99
247
  annotationsState
100
- ], (state2) => {
101
- const annotations2 = state2.field(annotationsState);
248
+ ], (state) => {
249
+ const annotations2 = state.field(annotationsState);
102
250
  const decorations = annotations2.map((annotation) => {
103
- const range = Cursor.getRangeFromCursor(state2, annotation.cursor);
251
+ const range = Cursor.getRangeFromCursor(state, annotation.cursor);
104
252
  return range && annotationMark.range(range.from, range.to);
105
253
  }).filter(isNotFalsy);
106
254
  return Decoration.set(decorations);
@@ -163,16 +311,16 @@ import { EditorView as EditorView2, ViewPlugin } from "@codemirror/view";
163
311
  import { next as A3 } from "@dxos/automerge/automerge";
164
312
 
165
313
  // packages/ui/react-ui-editor/src/extensions/automerge/cursor.ts
166
- import { log } from "@dxos/log";
314
+ import { log as log2 } from "@dxos/log";
167
315
  import { fromCursor, toCursor } from "@dxos/react-client/echo";
168
- var __dxlog_file = "/home/runner/work/dxos/dxos/packages/ui/react-ui-editor/src/extensions/automerge/cursor.ts";
316
+ var __dxlog_file2 = "/home/runner/work/dxos/dxos/packages/ui/react-ui-editor/src/extensions/automerge/cursor.ts";
169
317
  var cursorConverter = (accessor) => ({
170
318
  toCursor: (pos, assoc) => {
171
319
  try {
172
320
  return toCursor(accessor, pos, assoc);
173
321
  } catch (err) {
174
- log.catch(err, void 0, {
175
- F: __dxlog_file,
322
+ log2.catch(err, void 0, {
323
+ F: __dxlog_file2,
176
324
  L: 15,
177
325
  S: void 0,
178
326
  C: (f, a) => f(...a)
@@ -184,8 +332,8 @@ var cursorConverter = (accessor) => ({
184
332
  try {
185
333
  return fromCursor(accessor, cursor);
186
334
  } catch (err) {
187
- log.catch(err, void 0, {
188
- F: __dxlog_file,
335
+ log2.catch(err, void 0, {
336
+ F: __dxlog_file2,
189
337
  L: 24,
190
338
  S: void 0,
191
339
  C: (f, a) => f(...a)
@@ -197,8 +345,8 @@ var cursorConverter = (accessor) => ({
197
345
 
198
346
  // packages/ui/react-ui-editor/src/extensions/automerge/defs.ts
199
347
  import { Annotation, StateEffect } from "@codemirror/state";
200
- var getPath = (state2, field) => state2.field(field).path;
201
- var getLastHeads = (state2, field) => state2.field(field).lastHeads;
348
+ var getPath = (state, field) => state.field(field).path;
349
+ var getLastHeads = (state, field) => state.field(field).lastHeads;
202
350
  var updateHeadsEffect = StateEffect.define({});
203
351
  var updateHeads = (newHeads) => updateHeadsEffect.of({
204
352
  newHeads
@@ -213,8 +361,8 @@ import { next as A2 } from "@dxos/automerge/automerge";
213
361
 
214
362
  // packages/ui/react-ui-editor/src/extensions/automerge/update-automerge.ts
215
363
  import { next as A } from "@dxos/automerge/automerge";
216
- var updateAutomerge = (field, handle, transactions, state2) => {
217
- const { lastHeads, path } = state2.field(field);
364
+ var updateAutomerge = (field, handle, transactions, state) => {
365
+ const { lastHeads, path } = state.field(field);
218
366
  let hasChanges = false;
219
367
  for (const tr of transactions) {
220
368
  tr.changes.iterChanges(() => {
@@ -261,7 +409,7 @@ var updateCodeMirror = (view, selection, target, patches) => {
261
409
  annotations: reconcileAnnotation.of(false)
262
410
  });
263
411
  };
264
- var handlePatch = (patch, target, state2) => {
412
+ var handlePatch = (patch, target, state) => {
265
413
  if (patch.action === "insert") {
266
414
  return handleInsert(target, patch);
267
415
  } else if (patch.action === "splice") {
@@ -269,7 +417,7 @@ var handlePatch = (patch, target, state2) => {
269
417
  } else if (patch.action === "del") {
270
418
  return handleDel(target, patch);
271
419
  } else if (patch.action === "put") {
272
- return handlePut(target, patch, state2);
420
+ return handlePut(target, patch, state);
273
421
  } else {
274
422
  return null;
275
423
  }
@@ -313,7 +461,7 @@ var handleDel = (target, patch) => {
313
461
  }
314
462
  ];
315
463
  };
316
- var handlePut = (target, patch, state2) => {
464
+ var handlePut = (target, patch, state) => {
317
465
  const index = charPath(target, [
318
466
  ...patch.path,
319
467
  0
@@ -321,7 +469,7 @@ var handlePut = (target, patch, state2) => {
321
469
  if (index == null) {
322
470
  return [];
323
471
  }
324
- const length = state2.doc.length;
472
+ const length = state.doc.length;
325
473
  if (typeof patch.value !== "string") {
326
474
  return [];
327
475
  }
@@ -456,7 +604,7 @@ import { Annotation as Annotation2, RangeSet } from "@codemirror/state";
456
604
  import { Decoration as Decoration2, EditorView as EditorView3, ViewPlugin as ViewPlugin2, WidgetType } from "@codemirror/view";
457
605
  import { Event } from "@dxos/async";
458
606
  import { Context } from "@dxos/context";
459
- var __dxlog_file2 = "/home/runner/work/dxos/dxos/packages/ui/react-ui-editor/src/extensions/awareness/awareness.ts";
607
+ var __dxlog_file3 = "/home/runner/work/dxos/dxos/packages/ui/react-ui-editor/src/extensions/awareness/awareness.ts";
460
608
  var dummyProvider = {
461
609
  remoteStateChange: new Event(),
462
610
  open: () => {
@@ -481,7 +629,7 @@ var awareness = (provider = dummyProvider) => {
481
629
  var RemoteSelectionsDecorator = class {
482
630
  constructor(view) {
483
631
  this._ctx = new Context(void 0, {
484
- F: __dxlog_file2,
632
+ F: __dxlog_file3,
485
633
  L: 80
486
634
  });
487
635
  this.decorations = RangeSet.of([]);
@@ -520,9 +668,9 @@ var RemoteSelectionsDecorator = class {
520
668
  _updateRemoteSelections(view) {
521
669
  const decorations = [];
522
670
  const awarenessStates = this._provider.getRemoteStates();
523
- for (const state2 of awarenessStates) {
524
- const anchor = state2.position?.anchor ? this._cursorConverter.fromCursor(state2.position.anchor) : null;
525
- const head = state2.position?.head ? this._cursorConverter.fromCursor(state2.position.head) : null;
671
+ for (const state of awarenessStates) {
672
+ const anchor = state.position?.anchor ? this._cursorConverter.fromCursor(state.position.anchor) : null;
673
+ const head = state.position?.head ? this._cursorConverter.fromCursor(state.position.head) : null;
526
674
  if (anchor == null || head == null) {
527
675
  continue;
528
676
  }
@@ -530,8 +678,8 @@ var RemoteSelectionsDecorator = class {
530
678
  const end = Math.min(Math.max(anchor, head), view.state.doc.length);
531
679
  const startLine = view.state.doc.lineAt(start);
532
680
  const endLine = view.state.doc.lineAt(end);
533
- const darkColor = state2.info.darkColor;
534
- const lightColor = state2.info.lightColor;
681
+ const darkColor = state.info.darkColor;
682
+ const lightColor = state.info.lightColor;
535
683
  if (startLine.number === endLine.number) {
536
684
  decorations.push({
537
685
  from: start,
@@ -584,7 +732,7 @@ var RemoteSelectionsDecorator = class {
584
732
  value: Decoration2.widget({
585
733
  side: head - anchor > 0 ? -1 : 1,
586
734
  block: false,
587
- widget: new RemoteCaretWidget(state2.info.displayName ?? "Anonymous", darkColor)
735
+ widget: new RemoteCaretWidget(state.info.displayName ?? "Anonymous", darkColor)
588
736
  })
589
737
  });
590
738
  }
@@ -689,8 +837,8 @@ var styles2 = EditorView3.theme({
689
837
  import { DeferredTask, Event as Event2, sleep } from "@dxos/async";
690
838
  import { Context as Context2 } from "@dxos/context";
691
839
  import { invariant } from "@dxos/invariant";
692
- import { log as log2 } from "@dxos/log";
693
- var __dxlog_file3 = "/home/runner/work/dxos/dxos/packages/ui/react-ui-editor/src/extensions/awareness/awareness-provider.ts";
840
+ import { log as log3 } from "@dxos/log";
841
+ var __dxlog_file4 = "/home/runner/work/dxos/dxos/packages/ui/react-ui-editor/src/extensions/awareness/awareness-provider.ts";
694
842
  var DEBOUNCE_INTERVAL = 100;
695
843
  var SpaceAwarenessProvider = class {
696
844
  constructor(params) {
@@ -703,7 +851,7 @@ var SpaceAwarenessProvider = class {
703
851
  }
704
852
  open() {
705
853
  this._ctx = new Context2(void 0, {
706
- F: __dxlog_file3,
854
+ F: __dxlog_file4,
707
855
  L: 57
708
856
  });
709
857
  this._postTask = new DeferredTask(this._ctx, async () => {
@@ -730,10 +878,10 @@ var SpaceAwarenessProvider = class {
730
878
  void this._space.postMessage(this._channel, {
731
879
  kind: "query"
732
880
  }).catch((err) => {
733
- log2.debug("failed to query awareness", {
881
+ log3.debug("failed to query awareness", {
734
882
  err
735
883
  }, {
736
- F: __dxlog_file3,
884
+ F: __dxlog_file4,
737
885
  L: 91,
738
886
  S: this,
739
887
  C: (f, a) => f(...a)
@@ -750,7 +898,7 @@ var SpaceAwarenessProvider = class {
750
898
  }
751
899
  update(position) {
752
900
  invariant(this._postTask, void 0, {
753
- F: __dxlog_file3,
901
+ F: __dxlog_file4,
754
902
  L: 106,
755
903
  S: this,
756
904
  A: [
@@ -767,7 +915,7 @@ var SpaceAwarenessProvider = class {
767
915
  }
768
916
  _handleQueryMessage() {
769
917
  invariant(this._postTask, void 0, {
770
- F: __dxlog_file3,
918
+ F: __dxlog_file4,
771
919
  L: 117,
772
920
  S: this,
773
921
  A: [
@@ -779,7 +927,7 @@ var SpaceAwarenessProvider = class {
779
927
  }
780
928
  _handlePostMessage(message) {
781
929
  invariant(message.kind === "post", void 0, {
782
- F: __dxlog_file3,
930
+ F: __dxlog_file4,
783
931
  L: 122,
784
932
  S: this,
785
933
  A: [
@@ -796,7 +944,7 @@ var SpaceAwarenessProvider = class {
796
944
  import { EditorView as EditorView4, keymap as keymap2 } from "@codemirror/view";
797
945
  import defaultsDeep from "lodash.defaultsdeep";
798
946
  import { invariant as invariant2 } from "@dxos/invariant";
799
- var __dxlog_file4 = "/home/runner/work/dxos/dxos/packages/ui/react-ui-editor/src/extensions/blast.ts";
947
+ var __dxlog_file5 = "/home/runner/work/dxos/dxos/packages/ui/react-ui-editor/src/extensions/blast.ts";
800
948
  var defaultOptions = {
801
949
  effect: 2,
802
950
  maxParticles: 200,
@@ -923,7 +1071,7 @@ var Blaster = class {
923
1071
  }
924
1072
  initialize() {
925
1073
  invariant2(!this._canvas && !this._ctx, void 0, {
926
- F: __dxlog_file4,
1074
+ F: __dxlog_file5,
927
1075
  L: 141,
928
1076
  S: this,
929
1077
  A: [
@@ -960,7 +1108,7 @@ var Blaster = class {
960
1108
  }
961
1109
  start() {
962
1110
  invariant2(this._canvas && this._ctx, void 0, {
963
- F: __dxlog_file4,
1111
+ F: __dxlog_file5,
964
1112
  L: 180,
965
1113
  S: this,
966
1114
  A: [
@@ -1115,7 +1263,7 @@ import { showTooltip } from "@codemirror/view";
1115
1263
  var commandConfig = singleValueFacet();
1116
1264
  var commandState = StateField3.define({
1117
1265
  create: () => ({}),
1118
- update: (state2, tr) => {
1266
+ update: (state, tr) => {
1119
1267
  for (const effect of tr.effects) {
1120
1268
  if (effect.is(closeEffect)) {
1121
1269
  return {};
@@ -1166,7 +1314,7 @@ var commandState = StateField3.define({
1166
1314
  };
1167
1315
  }
1168
1316
  }
1169
- return state2;
1317
+ return state;
1170
1318
  },
1171
1319
  provide: (field) => [
1172
1320
  showTooltip.from(field, (value) => value.tooltip ?? null)
@@ -1210,78 +1358,6 @@ var commandKeyBindings = [
1210
1358
  }
1211
1359
  ];
1212
1360
 
1213
- // packages/ui/react-ui-editor/src/extensions/util/dom.ts
1214
- var flattenRect = (rect, left) => {
1215
- const x = left ? rect.left : rect.right;
1216
- return {
1217
- left: x,
1218
- right: x,
1219
- top: rect.top,
1220
- bottom: rect.bottom
1221
- };
1222
- };
1223
- var scratchRange;
1224
- var textRange = (node, from, to = from) => {
1225
- const range = scratchRange || (scratchRange = document.createRange());
1226
- range.setEnd(node, to);
1227
- range.setStart(node, from);
1228
- return range;
1229
- };
1230
- var clientRectsFor = (dom) => {
1231
- if (dom.nodeType === 3) {
1232
- return textRange(dom, 0, dom.nodeValue.length).getClientRects();
1233
- } else if (dom.nodeType === 1) {
1234
- return dom.getClientRects();
1235
- } else {
1236
- return [];
1237
- }
1238
- };
1239
-
1240
- // packages/ui/react-ui-editor/src/extensions/util/error.ts
1241
- import { log as log3 } from "@dxos/log";
1242
- var __dxlog_file5 = "/home/runner/work/dxos/dxos/packages/ui/react-ui-editor/src/extensions/util/error.ts";
1243
- var wrapWithCatch = (fn) => {
1244
- return (...args) => {
1245
- try {
1246
- return fn(...args);
1247
- } catch (err) {
1248
- log3.catch(err, void 0, {
1249
- F: __dxlog_file5,
1250
- L: 12,
1251
- S: void 0,
1252
- C: (f, a) => f(...a)
1253
- });
1254
- }
1255
- };
1256
- };
1257
-
1258
- // packages/ui/react-ui-editor/src/extensions/util/overlap.ts
1259
- var overlap = (a, b) => a.from <= b.to && a.to >= b.from;
1260
-
1261
- // packages/ui/react-ui-editor/src/extensions/util/react.tsx
1262
- import React from "react";
1263
- import { createRoot } from "react-dom/client";
1264
- import { ThemeProvider } from "@dxos/react-ui";
1265
- import { defaultTx } from "@dxos/react-ui-theme";
1266
- var createElement = (tag, options, children) => {
1267
- const el = document.createElement(tag);
1268
- if (options?.className) {
1269
- el.className = options.className;
1270
- }
1271
- if (children) {
1272
- el.append(...Array.isArray(children) ? children : [
1273
- children
1274
- ]);
1275
- }
1276
- return el;
1277
- };
1278
- var renderRoot = (root, node) => {
1279
- createRoot(root).render(/* @__PURE__ */ React.createElement(ThemeProvider, {
1280
- tx: defaultTx
1281
- }, node));
1282
- return root;
1283
- };
1284
-
1285
1361
  // packages/ui/react-ui-editor/src/extensions/command/hint.ts
1286
1362
  var CommandHint = class extends WidgetType2 {
1287
1363
  constructor(content) {
@@ -1365,57 +1441,104 @@ var command = (options) => {
1365
1441
  // packages/ui/react-ui-editor/src/extensions/comments.ts
1366
1442
  import { invertedEffects } from "@codemirror/commands";
1367
1443
  import { StateEffect as StateEffect3, StateField as StateField4 } from "@codemirror/state";
1368
- import { hoverTooltip, keymap as keymap4, Decoration as Decoration4, EditorView as EditorView7, ViewPlugin as ViewPlugin4 } from "@codemirror/view";
1444
+ import { hoverTooltip, keymap as keymap5, Decoration as Decoration4, EditorView as EditorView8, ViewPlugin as ViewPlugin4 } from "@codemirror/view";
1369
1445
  import sortBy from "lodash.sortby";
1370
1446
  import { useEffect, useMemo, useState } from "react";
1371
- import { debounce } from "@dxos/async";
1372
- import { log as log5 } from "@dxos/log";
1447
+ import { debounce as debounce2 } from "@dxos/async";
1448
+ import { log as log4 } from "@dxos/log";
1373
1449
  import { nonNullable } from "@dxos/util";
1374
1450
 
1375
- // packages/ui/react-ui-editor/src/util.ts
1376
- import { log as log4 } from "@dxos/log";
1377
- var __dxlog_file6 = "/home/runner/work/dxos/dxos/packages/ui/react-ui-editor/src/util.ts";
1378
- var callbackWrapper = (fn) => (...args) => {
1379
- try {
1380
- return fn(...args);
1381
- } catch (err) {
1382
- log4.catch(err, void 0, {
1451
+ // packages/ui/react-ui-editor/src/extensions/selection.ts
1452
+ import { Transaction } from "@codemirror/state";
1453
+ import { EditorView as EditorView7, keymap as keymap4 } from "@codemirror/view";
1454
+ import { debounce } from "@dxos/async";
1455
+ import { invariant as invariant3 } from "@dxos/invariant";
1456
+ import { isNotFalsy as isNotFalsy2 } from "@dxos/util";
1457
+ var __dxlog_file6 = "/home/runner/work/dxos/dxos/packages/ui/react-ui-editor/src/extensions/selection.ts";
1458
+ var documentId = singleValueFacet();
1459
+ var stateRestoreAnnotation = "dxos.org/cm/state-restore";
1460
+ var createEditorStateTransaction = ({ scrollTo, selection }) => {
1461
+ return {
1462
+ selection,
1463
+ scrollIntoView: !scrollTo,
1464
+ effects: scrollTo ? EditorView7.scrollIntoView(scrollTo, {
1465
+ yMargin: 96
1466
+ }) : void 0,
1467
+ annotations: Transaction.userEvent.of(stateRestoreAnnotation)
1468
+ };
1469
+ };
1470
+ var createEditorStateStore = (keyPrefix) => ({
1471
+ getState: (id) => {
1472
+ invariant3(id, void 0, {
1383
1473
  F: __dxlog_file6,
1384
- L: 19,
1474
+ L: 47,
1385
1475
  S: void 0,
1386
- C: (f, a) => f(...a)
1476
+ A: [
1477
+ "id",
1478
+ ""
1479
+ ]
1387
1480
  });
1388
- }
1389
- };
1390
- var debugDispatcher = (trs, view) => {
1391
- logChanges(trs);
1392
- view.update(trs);
1393
- };
1394
- var logChanges = (trs) => {
1395
- const changes = trs.flatMap((tr) => {
1396
- if (tr.changes.empty) {
1397
- return void 0;
1398
- }
1399
- const changes2 = [];
1400
- tr.changes.iterChanges((fromA, toA, fromB, toB, inserted) => changes2.push(JSON.stringify({
1401
- fromA,
1402
- toA,
1403
- fromB,
1404
- toB,
1405
- inserted: inserted.toString()
1406
- })));
1407
- return changes2;
1408
- }).filter(Boolean);
1409
- if (changes.length) {
1410
- log4.info("changes", {
1411
- changes
1412
- }, {
1481
+ const state = localStorage.getItem(`${keyPrefix}/${id}`);
1482
+ return state ? JSON.parse(state) : void 0;
1483
+ },
1484
+ setState: (id, state) => {
1485
+ invariant3(id, void 0, {
1413
1486
  F: __dxlog_file6,
1414
- L: 49,
1487
+ L: 53,
1415
1488
  S: void 0,
1416
- C: (f, a) => f(...a)
1489
+ A: [
1490
+ "id",
1491
+ ""
1492
+ ]
1417
1493
  });
1494
+ localStorage.setItem(`${keyPrefix}/${id}`, JSON.stringify(state));
1418
1495
  }
1496
+ });
1497
+ var selectionState = ({ getState, setState } = {}) => {
1498
+ const setStateDebounced = debounce(setState, 1e3);
1499
+ return [
1500
+ // TODO(burdon): Track scrolling (currently only updates when cursor moves).
1501
+ // EditorView.domEventHandlers({
1502
+ // scroll: (event) => {
1503
+ // setStateDebounced(id, {});
1504
+ // },
1505
+ // }),
1506
+ EditorView7.updateListener.of(({ view, transactions }) => {
1507
+ const id = view.state.facet(documentId);
1508
+ if (!id || transactions.some((tr) => tr.isUserEvent(stateRestoreAnnotation))) {
1509
+ return;
1510
+ }
1511
+ if (setState) {
1512
+ const { scrollTop } = view.scrollDOM;
1513
+ const pos = view.posAtCoords({
1514
+ x: 0,
1515
+ y: scrollTop
1516
+ });
1517
+ if (pos !== null) {
1518
+ const { anchor, head } = view.state.selection.main;
1519
+ setStateDebounced(id, {
1520
+ scrollTo: pos,
1521
+ selection: {
1522
+ anchor,
1523
+ head
1524
+ }
1525
+ });
1526
+ }
1527
+ }
1528
+ }),
1529
+ getState && keymap4.of([
1530
+ {
1531
+ key: "ctrl-r",
1532
+ run: (view) => {
1533
+ const state = getState(view.state.facet(documentId));
1534
+ if (state) {
1535
+ view.dispatch(createEditorStateTransaction(state));
1536
+ }
1537
+ return true;
1538
+ }
1539
+ }
1540
+ ])
1541
+ ].filter(isNotFalsy2);
1419
1542
  };
1420
1543
 
1421
1544
  // packages/ui/react-ui-editor/src/extensions/comments.ts
@@ -1424,8 +1547,8 @@ var setComments = StateEffect3.define();
1424
1547
  var setSelection = StateEffect3.define();
1425
1548
  var setCommentState = StateEffect3.define();
1426
1549
  var commentsState = StateField4.define({
1427
- create: (state2) => ({
1428
- id: state2.facet(documentId),
1550
+ create: (state) => ({
1551
+ id: state.facet(documentId),
1429
1552
  comments: [],
1430
1553
  selection: {}
1431
1554
  }),
@@ -1461,7 +1584,7 @@ var commentsState = StateField4.define({
1461
1584
  return value;
1462
1585
  }
1463
1586
  });
1464
- var styles3 = EditorView7.theme({
1587
+ var styles3 = EditorView8.theme({
1465
1588
  ".cm-comment, .cm-comment-current": {
1466
1589
  margin: "0 -3px",
1467
1590
  padding: "3px",
@@ -1481,16 +1604,16 @@ var createCommentMark = (id, isCurrent) => Decoration4.mark({
1481
1604
  "data-comment-id": id
1482
1605
  }
1483
1606
  });
1484
- var commentsDecorations = EditorView7.decorations.compute([
1607
+ var commentsDecorations = EditorView8.decorations.compute([
1485
1608
  commentsState
1486
- ], (state2) => {
1487
- const { selection: { current }, comments: comments2 } = state2.field(commentsState);
1609
+ ], (state) => {
1610
+ const { selection: { current }, comments: comments2 } = state.field(commentsState);
1488
1611
  const decorations = sortBy(comments2 ?? [], (range) => range.range.from)?.flatMap((comment) => {
1489
1612
  const range = comment.range;
1490
1613
  if (!range) {
1491
- log5.warn("Invalid range:", range, {
1614
+ log4.warn("Invalid range:", range, {
1492
1615
  F: __dxlog_file7,
1493
- L: 143,
1616
+ L: 142,
1494
1617
  S: void 0,
1495
1618
  C: (f, a) => f(...a)
1496
1619
  });
@@ -1504,7 +1627,7 @@ var commentsDecorations = EditorView7.decorations.compute([
1504
1627
  return Decoration4.set(decorations);
1505
1628
  });
1506
1629
  var commentClickedEffect = StateEffect3.define();
1507
- var handleCommentClick = EditorView7.domEventHandlers({
1630
+ var handleCommentClick = EditorView8.domEventHandlers({
1508
1631
  click: (event, view) => {
1509
1632
  let target = event.target;
1510
1633
  const editorRoot = view.dom;
@@ -1543,7 +1666,7 @@ var trackPastedComments = (onUpdate) => {
1543
1666
  }
1544
1667
  };
1545
1668
  return [
1546
- EditorView7.domEventHandlers({
1669
+ EditorView8.domEventHandlers({
1547
1670
  cut: handleTrack,
1548
1671
  copy: handleTrack
1549
1672
  }),
@@ -1565,7 +1688,7 @@ var trackPastedComments = (onUpdate) => {
1565
1688
  return effects;
1566
1689
  }),
1567
1690
  // Handle paste or the undo of comment deletion.
1568
- EditorView7.updateListener.of((update2) => {
1691
+ EditorView8.updateListener.of((update2) => {
1569
1692
  const restore = [];
1570
1693
  for (let i = 0; i < update2.transactions.length; i++) {
1571
1694
  const tr = update2.transactions[i];
@@ -1655,7 +1778,7 @@ var createComment = (view) => {
1655
1778
  var optionsFacet = singleValueFacet();
1656
1779
  var comments = (options = {}) => {
1657
1780
  const { key: shortcut = "meta-'" } = options;
1658
- const handleSelect = debounce((state2) => options.onSelect?.(state2), 200);
1781
+ const handleSelect = debounce2((state) => options.onSelect?.(state), 200);
1659
1782
  return [
1660
1783
  optionsFacet.of(options),
1661
1784
  options.id ? documentId.of(options.id) : void 0,
@@ -1666,7 +1789,7 @@ var comments = (options = {}) => {
1666
1789
  //
1667
1790
  // Keymap.
1668
1791
  //
1669
- options.onCreate && keymap4.of([
1792
+ options.onCreate && keymap5.of([
1670
1793
  {
1671
1794
  key: shortcut,
1672
1795
  run: callbackWrapper(createComment)
@@ -1705,9 +1828,9 @@ var comments = (options = {}) => {
1705
1828
  //
1706
1829
  // Track deleted ranges and update ranges for decorations.
1707
1830
  //
1708
- EditorView7.updateListener.of(({ view, state: state2, changes }) => {
1831
+ EditorView8.updateListener.of(({ view, state, changes }) => {
1709
1832
  let mod = false;
1710
- const { comments: comments2, ...value } = state2.field(commentsState);
1833
+ const { comments: comments2, ...value } = state.field(commentsState);
1711
1834
  changes.iterChanges((from, to, from2, to2) => {
1712
1835
  comments2.forEach(({ comment, range }) => {
1713
1836
  if (from2 === to2) {
@@ -1737,10 +1860,10 @@ var comments = (options = {}) => {
1737
1860
  //
1738
1861
  // Track selection/proximity.
1739
1862
  //
1740
- EditorView7.updateListener.of(({ view, state: state2 }) => {
1863
+ EditorView8.updateListener.of(({ view, state }) => {
1741
1864
  let min = Infinity;
1742
- const { selection: { current, closest }, comments: comments2 } = state2.field(commentsState);
1743
- const { head } = state2.selection.main;
1865
+ const { selection: { current, closest }, comments: comments2 } = state.field(commentsState);
1866
+ const { head } = state.selection.main;
1744
1867
  const selection = {};
1745
1868
  comments2.forEach(({ comment, range }) => {
1746
1869
  if (head >= range.from && head <= range.to) {
@@ -1761,7 +1884,7 @@ var comments = (options = {}) => {
1761
1884
  });
1762
1885
  handleSelect({
1763
1886
  selection,
1764
- id: state2.facet(documentId),
1887
+ id: state.facet(documentId),
1765
1888
  comments: comments2.map(({ comment, range }) => ({
1766
1889
  comment,
1767
1890
  range,
@@ -1791,7 +1914,7 @@ var scrollThreadIntoView = (view, id, center = true) => {
1791
1914
  anchor: range.from
1792
1915
  } : void 0,
1793
1916
  effects: [
1794
- needsScroll ? EditorView7.scrollIntoView(range.from, center ? {
1917
+ needsScroll ? EditorView8.scrollIntoView(range.from, center ? {
1795
1918
  y: "center"
1796
1919
  } : void 0) : [],
1797
1920
  needsSelectionUpdate ? setSelection.of({
@@ -1802,12 +1925,12 @@ var scrollThreadIntoView = (view, id, center = true) => {
1802
1925
  }
1803
1926
  }
1804
1927
  };
1805
- var selectionOverlapsComment = (state2) => {
1806
- const commentState = state2.field(commentsState, false);
1928
+ var selectionOverlapsComment = (state) => {
1929
+ const commentState = state.field(commentsState, false);
1807
1930
  if (commentState === void 0) {
1808
1931
  return false;
1809
1932
  }
1810
- const { selection } = state2;
1933
+ const { selection } = state;
1811
1934
  for (const range of selection.ranges) {
1812
1935
  if (commentState.comments.some(({ range: commentRange }) => overlap(commentRange, range))) {
1813
1936
  return true;
@@ -1815,8 +1938,8 @@ var selectionOverlapsComment = (state2) => {
1815
1938
  }
1816
1939
  return false;
1817
1940
  };
1818
- var hasActiveSelection = (state2) => {
1819
- return state2.selection.ranges.some((range) => !range.empty);
1941
+ var hasActiveSelection = (state) => {
1942
+ return state.selection.ranges.some((range) => !range.empty);
1820
1943
  };
1821
1944
  var ExternalCommentSync = class {
1822
1945
  constructor(view, id, subscribe, getComments) {
@@ -1843,11 +1966,11 @@ var createExternalCommentSync = (id, subscribe, getComments) => ViewPlugin4.from
1843
1966
  }
1844
1967
  });
1845
1968
  var useCommentState = () => {
1846
- const [state2, setState] = useState({
1969
+ const [state, setState] = useState({
1847
1970
  comment: false,
1848
1971
  selection: false
1849
1972
  });
1850
- const observer = useMemo(() => EditorView7.updateListener.of((update2) => {
1973
+ const observer = useMemo(() => EditorView8.updateListener.of((update2) => {
1851
1974
  if (update2.docChanged || update2.selectionSet) {
1852
1975
  setState({
1853
1976
  comment: selectionOverlapsComment(update2.state),
@@ -1856,7 +1979,7 @@ var useCommentState = () => {
1856
1979
  }
1857
1980
  }), []);
1858
1981
  return [
1859
- state2,
1982
+ state,
1860
1983
  observer
1861
1984
  ];
1862
1985
  };
@@ -1875,7 +1998,7 @@ var useComments = (view, id, comments2) => {
1875
1998
  });
1876
1999
  };
1877
2000
  var useCommentClickListener = (onCommentClick) => {
1878
- return useMemo(() => EditorView7.updateListener.of((update2) => {
2001
+ return useMemo(() => EditorView8.updateListener.of((update2) => {
1879
2002
  update2.transactions.forEach((transaction) => {
1880
2003
  transaction.effects.forEach((effect) => {
1881
2004
  if (effect.is(commentClickedEffect)) {
@@ -1891,19 +2014,19 @@ var useCommentClickListener = (onCommentClick) => {
1891
2014
  // packages/ui/react-ui-editor/src/extensions/debug.ts
1892
2015
  import { syntaxTree } from "@codemirror/language";
1893
2016
  import { StateField as StateField5 } from "@codemirror/state";
1894
- var debugNodeLogger = (log9 = console.log) => {
1895
- const logTokens = (state2) => syntaxTree(state2).iterate({
1896
- enter: (node) => log9(node.type)
2017
+ var debugNodeLogger = (log8 = console.log) => {
2018
+ const logTokens = (state) => syntaxTree(state).iterate({
2019
+ enter: (node) => log8(node.type)
1897
2020
  });
1898
2021
  return StateField5.define({
1899
- create: (state2) => logTokens(state2),
2022
+ create: (state) => logTokens(state),
1900
2023
  update: (_, tr) => logTokens(tr.state)
1901
2024
  });
1902
2025
  };
1903
2026
 
1904
2027
  // packages/ui/react-ui-editor/src/extensions/dnd.ts
1905
- import { dropCursor, EditorView as EditorView8 } from "@codemirror/view";
1906
- var styles4 = EditorView8.theme({
2028
+ import { dropCursor, EditorView as EditorView9 } from "@codemirror/view";
2029
+ var styles4 = EditorView9.theme({
1907
2030
  ".cm-dropCursor": {
1908
2031
  borderLeft: "2px solid var(--dx-accentText)",
1909
2032
  color: "var(--dx-accentText)",
@@ -1917,7 +2040,7 @@ var dropFile = (options = {}) => {
1917
2040
  return [
1918
2041
  styles4,
1919
2042
  dropCursor(),
1920
- EditorView8.domEventHandlers({
2043
+ EditorView9.domEventHandlers({
1921
2044
  drop: (event, view) => {
1922
2045
  event.preventDefault();
1923
2046
  const files = event.dataTransfer?.files;
@@ -1944,13 +2067,44 @@ import { bracketMatching, defaultHighlightStyle, syntaxHighlighting } from "@cod
1944
2067
  import { searchKeymap } from "@codemirror/search";
1945
2068
  import { EditorState } from "@codemirror/state";
1946
2069
  import { oneDarkHighlightStyle } from "@codemirror/theme-one-dark";
1947
- import { EditorView as EditorView9, drawSelection, dropCursor as dropCursor2, highlightActiveLine, keymap as keymap5, lineNumbers, placeholder, scrollPastEnd } from "@codemirror/view";
2070
+ import { EditorView as EditorView11, drawSelection, dropCursor as dropCursor2, highlightActiveLine, keymap as keymap6, lineNumbers, placeholder, scrollPastEnd } from "@codemirror/view";
1948
2071
  import defaultsDeep2 from "lodash.defaultsdeep";
1949
2072
  import merge from "lodash.merge";
1950
2073
  import { generateName } from "@dxos/display-name";
1951
- import { log as log6 } from "@dxos/log";
2074
+ import { log as log5 } from "@dxos/log";
1952
2075
  import { hueTokens } from "@dxos/react-ui-theme";
1953
- import { hexToHue, isNotFalsy as isNotFalsy2 } from "@dxos/util";
2076
+ import { hexToHue, isNotFalsy as isNotFalsy3 } from "@dxos/util";
2077
+
2078
+ // packages/ui/react-ui-editor/src/extensions/focus.ts
2079
+ import { StateEffect as StateEffect4, StateField as StateField6 } from "@codemirror/state";
2080
+ import { EditorView as EditorView10 } from "@codemirror/view";
2081
+ var focusEffect = StateEffect4.define();
2082
+ var focusField = StateField6.define({
2083
+ create: () => false,
2084
+ update: (value, tr) => {
2085
+ for (const effect of tr.effects) {
2086
+ if (effect.is(focusEffect)) {
2087
+ return effect.value;
2088
+ }
2089
+ }
2090
+ return value;
2091
+ }
2092
+ });
2093
+ var focus = [
2094
+ focusField,
2095
+ EditorView10.domEventHandlers({
2096
+ focus: (event, view) => {
2097
+ setTimeout(() => view.dispatch({
2098
+ effects: focusEffect.of(true)
2099
+ }));
2100
+ },
2101
+ blur: (event, view) => {
2102
+ setTimeout(() => view.dispatch({
2103
+ effects: focusEffect.of(false)
2104
+ }));
2105
+ }
2106
+ })
2107
+ ];
1954
2108
 
1955
2109
  // packages/ui/react-ui-editor/src/styles/markdown.ts
1956
2110
  import { mx } from "@dxos/react-ui-theme";
@@ -2189,6 +2343,7 @@ var defaultBasicOptions = {
2189
2343
  closeBrackets: true,
2190
2344
  drawSelection: true,
2191
2345
  editable: true,
2346
+ focus: true,
2192
2347
  history: true,
2193
2348
  keymap: "standard",
2194
2349
  lineWrapping: true,
@@ -2204,10 +2359,10 @@ var createBasicExtensions = (_props) => {
2204
2359
  const props = defaultsDeep2({}, _props, defaultBasicOptions);
2205
2360
  return [
2206
2361
  // NOTE: Doesn't catch errors in keymap functions.
2207
- EditorView9.exceptionSink.of((err) => {
2208
- log6.catch(err, void 0, {
2362
+ EditorView11.exceptionSink.of((err) => {
2363
+ log5.catch(err, void 0, {
2209
2364
  F: __dxlog_file8,
2210
- L: 93,
2365
+ L: 96,
2211
2366
  S: void 0,
2212
2367
  C: (f, a) => f(...a)
2213
2368
  });
@@ -2219,19 +2374,20 @@ var createBasicExtensions = (_props) => {
2219
2374
  props.drawSelection && drawSelection({
2220
2375
  cursorBlinkRate: 1200
2221
2376
  }),
2377
+ props.focus && focus,
2222
2378
  props.highlightActiveLine && highlightActiveLine(),
2223
2379
  props.history && history(),
2224
2380
  props.lineNumbers && lineNumbers(),
2225
- props.lineWrapping && EditorView9.lineWrapping,
2381
+ props.lineWrapping && EditorView11.lineWrapping,
2226
2382
  props.placeholder && placeholder(props.placeholder),
2227
2383
  props.readonly && [
2228
2384
  EditorState.readOnly.of(true),
2229
- EditorView9.editable.of(false)
2385
+ EditorView11.editable.of(false)
2230
2386
  ],
2231
2387
  props.scrollPastEnd && scrollPastEnd(),
2232
2388
  props.tabSize && EditorState.tabSize.of(props.tabSize),
2233
2389
  // https://codemirror.net/docs/ref/#view.KeyBinding
2234
- keymap5.of([
2390
+ keymap6.of([
2235
2391
  ...(props.keymap && keymaps[props.keymap]) ?? [],
2236
2392
  // NOTE: Tabs are also configured by markdown extension.
2237
2393
  // https://codemirror.net/docs/ref/#commands.indentWithTab
@@ -2244,8 +2400,8 @@ var createBasicExtensions = (_props) => {
2244
2400
  ...props.history ? historyKeymap : [],
2245
2401
  // https://codemirror.net/docs/ref/#search.searchKeymap
2246
2402
  ...props.search ? searchKeymap : []
2247
- ].filter(isNotFalsy2))
2248
- ].filter(isNotFalsy2);
2403
+ ].filter(isNotFalsy3))
2404
+ ].filter(isNotFalsy3);
2249
2405
  };
2250
2406
  var defaultThemeSlots = {
2251
2407
  editor: {
@@ -2255,17 +2411,17 @@ var defaultThemeSlots = {
2255
2411
  var createThemeExtensions = ({ themeMode, styles: styles5, syntaxHighlighting: _syntaxHighlighting, slots: _slots } = {}) => {
2256
2412
  const slots = defaultsDeep2({}, _slots, defaultThemeSlots);
2257
2413
  return [
2258
- EditorView9.darkTheme.of(themeMode === "dark"),
2259
- EditorView9.baseTheme(styles5 ? merge({}, defaultTheme, styles5) : defaultTheme),
2414
+ EditorView11.darkTheme.of(themeMode === "dark"),
2415
+ EditorView11.baseTheme(styles5 ? merge({}, defaultTheme, styles5) : defaultTheme),
2260
2416
  // https://github.com/codemirror/theme-one-dark
2261
2417
  _syntaxHighlighting && (themeMode === "dark" ? syntaxHighlighting(oneDarkHighlightStyle) : syntaxHighlighting(defaultHighlightStyle)),
2262
- slots.editor?.className && EditorView9.editorAttributes.of({
2418
+ slots.editor?.className && EditorView11.editorAttributes.of({
2263
2419
  class: slots.editor.className
2264
2420
  }),
2265
- slots.content?.className && EditorView9.contentAttributes.of({
2421
+ slots.content?.className && EditorView11.contentAttributes.of({
2266
2422
  class: slots.content.className
2267
2423
  })
2268
- ].filter(isNotFalsy2);
2424
+ ].filter(isNotFalsy3);
2269
2425
  };
2270
2426
  var createDataExtensions = ({ id, text, space, identity }) => {
2271
2427
  const extensions = [];
@@ -2291,7 +2447,7 @@ var createDataExtensions = ({ id, text, space, identity }) => {
2291
2447
 
2292
2448
  // packages/ui/react-ui-editor/src/extensions/folding.tsx
2293
2449
  import { codeFolding, foldGutter } from "@codemirror/language";
2294
- import { EditorView as EditorView10 } from "@codemirror/view";
2450
+ import { EditorView as EditorView12 } from "@codemirror/view";
2295
2451
  import React2 from "react";
2296
2452
  import { Icon } from "@dxos/react-ui";
2297
2453
  var folding = (_props = {}) => [
@@ -2315,7 +2471,7 @@ var folding = (_props = {}) => [
2315
2471
  }));
2316
2472
  }
2317
2473
  }),
2318
- EditorView10.theme({
2474
+ EditorView12.theme({
2319
2475
  ".cm-foldGutter": {
2320
2476
  opacity: 0.3,
2321
2477
  transition: "opacity 0.3s",
@@ -2328,14 +2484,14 @@ var folding = (_props = {}) => [
2328
2484
  ];
2329
2485
 
2330
2486
  // packages/ui/react-ui-editor/src/extensions/listener.ts
2331
- import { EditorView as EditorView11 } from "@codemirror/view";
2487
+ import { EditorView as EditorView13 } from "@codemirror/view";
2332
2488
  var listener = ({ onFocus, onChange }) => {
2333
2489
  const extensions = [];
2334
- onFocus && extensions.push(EditorView11.focusChangeEffect.of((_, focusing) => {
2490
+ onFocus && extensions.push(EditorView13.focusChangeEffect.of((_, focusing) => {
2335
2491
  onFocus(focusing);
2336
2492
  return null;
2337
2493
  }));
2338
- onChange && extensions.push(EditorView11.updateListener.of((update2) => {
2494
+ onChange && extensions.push(EditorView13.updateListener.of((update2) => {
2339
2495
  onChange(update2.state.doc.toString());
2340
2496
  }));
2341
2497
  return extensions;
@@ -2345,7 +2501,7 @@ var listener = ({ onFocus, onChange }) => {
2345
2501
  import { snippet } from "@codemirror/autocomplete";
2346
2502
  import { syntaxTree as syntaxTree2 } from "@codemirror/language";
2347
2503
  import { EditorSelection } from "@codemirror/state";
2348
- import { EditorView as EditorView12, keymap as keymap6 } from "@codemirror/view";
2504
+ import { EditorView as EditorView14, keymap as keymap7 } from "@codemirror/view";
2349
2505
  import { useMemo as useMemo2, useState as useState2 } from "react";
2350
2506
  var formattingEquals = (a, b) => a.blockType === b.blockType && a.strong === b.strong && a.emphasis === b.emphasis && a.strikethrough === b.strikethrough && a.code === b.code && a.link === b.link && a.listStyle === b.listStyle && a.blockQuote === b.blockQuote;
2351
2507
  var Inline;
@@ -2362,13 +2518,13 @@ var List;
2362
2518
  List2[List2["Task"] = 2] = "Task";
2363
2519
  })(List || (List = {}));
2364
2520
  var setHeading = (level) => {
2365
- return ({ state: state2, dispatch }) => {
2366
- const { selection: { ranges }, doc } = state2;
2521
+ return ({ state, dispatch }) => {
2522
+ const { selection: { ranges }, doc } = state;
2367
2523
  const changes = [];
2368
2524
  let prevBlock = -1;
2369
2525
  for (const range of ranges) {
2370
2526
  let sawBlock = false;
2371
- syntaxTree2(state2).iterate({
2527
+ syntaxTree2(state).iterate({
2372
2528
  from: range.from,
2373
2529
  to: range.to,
2374
2530
  enter: (node) => {
@@ -2421,7 +2577,7 @@ var setHeading = (level) => {
2421
2577
  }
2422
2578
  });
2423
2579
  let line;
2424
- if (!sawBlock && range.empty && level > 0 && !/\S/.test((line = state2.doc.lineAt(range.from)).text)) {
2580
+ if (!sawBlock && range.empty && level > 0 && !/\S/.test((line = state.doc.lineAt(range.from)).text)) {
2425
2581
  changes.push({
2426
2582
  from: line.from,
2427
2583
  to: line.to,
@@ -2432,10 +2588,10 @@ var setHeading = (level) => {
2432
2588
  if (!changes.length) {
2433
2589
  return false;
2434
2590
  }
2435
- const changeSet = state2.changes(changes);
2436
- dispatch(state2.update({
2591
+ const changeSet = state.changes(changes);
2592
+ dispatch(state.update({
2437
2593
  changes: changeSet,
2438
- selection: state2.selection.map(changeSet, 1),
2594
+ selection: state.selection.map(changeSet, 1),
2439
2595
  userEvent: "format.setHeading",
2440
2596
  scrollIntoView: true
2441
2597
  }));
@@ -2443,14 +2599,14 @@ var setHeading = (level) => {
2443
2599
  };
2444
2600
  };
2445
2601
  var setStyle = (type, enable) => {
2446
- return ({ state: state2, dispatch }) => {
2602
+ return ({ state, dispatch }) => {
2447
2603
  const marker = inlineMarkerText(type);
2448
- const changes = state2.changeByRange((range) => {
2604
+ const changes = state.changeByRange((range) => {
2449
2605
  if (!enable && range.empty) {
2450
- const after = state2.doc.sliceString(range.head, range.head + 6);
2606
+ const after = state.doc.sliceString(range.head, range.head + 6);
2451
2607
  const found = after.indexOf(marker);
2452
2608
  if (found >= 0 && /^[*~`]*$/.test(after.slice(0, found))) {
2453
- const before = state2.doc.sliceString(range.head - 6, range.head);
2609
+ const before = state.doc.sliceString(range.head - 6, range.head);
2454
2610
  if (before.slice(before.length - found - marker.length, before.length - found) === marker && [
2455
2611
  ...before.slice(before.length - found)
2456
2612
  ].reverse().join("") === after.slice(0, found)) {
@@ -2477,14 +2633,14 @@ var setStyle = (type, enable) => {
2477
2633
  let startCovered = false;
2478
2634
  let endCovered = false;
2479
2635
  let { from, to } = range;
2480
- syntaxTree2(state2).iterate({
2636
+ syntaxTree2(state).iterate({
2481
2637
  from,
2482
2638
  to,
2483
2639
  enter: (node) => {
2484
2640
  const { name } = node;
2485
2641
  if (Object.hasOwn(Textblocks, name) && Textblocks[name] !== "codeblock") {
2486
2642
  blockStart = blockContentStart(node);
2487
- blockEnd = blockContentEnd(node, state2.doc);
2643
+ blockEnd = blockContentEnd(node, state.doc);
2488
2644
  startCovered = endCovered = false;
2489
2645
  } else if (name === "Link" || name === "Image" && enable) {
2490
2646
  if (from < node.from && to > node.from && to <= node.to) {
@@ -2529,7 +2685,7 @@ var setStyle = (type, enable) => {
2529
2685
  });
2530
2686
  if (markType !== type && closeStart >= to) {
2531
2687
  changesAtEnd.push({
2532
- from: skipSpaces(Math.min(to, blockEnd), state2.doc, 1, blockEnd),
2688
+ from: skipSpaces(Math.min(to, blockEnd), state.doc, 1, blockEnd),
2533
2689
  insert: inlineMarkerText(markType)
2534
2690
  });
2535
2691
  }
@@ -2541,7 +2697,7 @@ var setStyle = (type, enable) => {
2541
2697
  });
2542
2698
  if (markType !== type && openEnd <= from) {
2543
2699
  changes2.push({
2544
- from: skipSpaces(Math.max(from, blockStart), state2.doc, -1, blockStart),
2700
+ from: skipSpaces(Math.max(from, blockStart), state.doc, -1, blockStart),
2545
2701
  insert: inlineMarkerText(markType)
2546
2702
  });
2547
2703
  }
@@ -2571,7 +2727,7 @@ var setStyle = (type, enable) => {
2571
2727
  changes2.push(startCovered);
2572
2728
  } else if (startCovered) {
2573
2729
  changes2.push({
2574
- from: skipSpaces(rangeStart, state2.doc, -1, blockStart),
2730
+ from: skipSpaces(rangeStart, state.doc, -1, blockStart),
2575
2731
  insert: marker
2576
2732
  });
2577
2733
  }
@@ -2579,7 +2735,7 @@ var setStyle = (type, enable) => {
2579
2735
  changes2.push(endCovered);
2580
2736
  } else if (endCovered) {
2581
2737
  changes2.push({
2582
- from: skipSpaces(rangeEnd, state2.doc, 1, blockEnd),
2738
+ from: skipSpaces(rangeEnd, state.doc, 1, blockEnd),
2583
2739
  insert: marker
2584
2740
  });
2585
2741
  }
@@ -2587,7 +2743,7 @@ var setStyle = (type, enable) => {
2587
2743
  }
2588
2744
  }
2589
2745
  });
2590
- if (blockStart < 0 && range.empty && enable && !/\S/.test(state2.doc.lineAt(range.from).text)) {
2746
+ if (blockStart < 0 && range.empty && enable && !/\S/.test(state.doc.lineAt(range.from).text)) {
2591
2747
  return {
2592
2748
  changes: {
2593
2749
  from: range.head,
@@ -2596,13 +2752,13 @@ var setStyle = (type, enable) => {
2596
2752
  range: EditorSelection.cursor(range.head + marker.length)
2597
2753
  };
2598
2754
  }
2599
- const changeSet = state2.changes(changes2.concat(changesAtEnd));
2755
+ const changeSet = state.changes(changes2.concat(changesAtEnd));
2600
2756
  return {
2601
2757
  changes: changeSet,
2602
2758
  range: range.empty && !changeSet.empty ? EditorSelection.cursor(range.head + marker.length) : EditorSelection.range(changeSet.mapPos(range.from, 1), changeSet.mapPos(range.to, -1))
2603
2759
  };
2604
2760
  });
2605
- dispatch(state2.update(changes, {
2761
+ dispatch(state.update(changes, {
2606
2762
  userEvent: enable ? "format.style.add" : "format.style.remove",
2607
2763
  scrollIntoView: true
2608
2764
  }));
@@ -2679,8 +2835,8 @@ var insertTable = (view) => {
2679
2835
  const { from } = doc.line(number);
2680
2836
  snippets.table(view, null, from, from);
2681
2837
  };
2682
- var removeLinkInner = (from, to, changes, state2) => {
2683
- syntaxTree2(state2).iterate({
2838
+ var removeLinkInner = (from, to, changes, state) => {
2839
+ syntaxTree2(state).iterate({
2684
2840
  from,
2685
2841
  to,
2686
2842
  enter: (node) => {
@@ -2694,8 +2850,8 @@ var removeLinkInner = (from, to, changes, state2) => {
2694
2850
  });
2695
2851
  } else if (name === "LinkTitle" || name === "URL") {
2696
2852
  changes.push({
2697
- from: skipSpaces(node2.from, state2.doc, -1),
2698
- to: skipSpaces(node2.to, state2.doc, 1)
2853
+ from: skipSpaces(node2.from, state.doc, -1),
2854
+ to: skipSpaces(node2.to, state.doc, 1)
2699
2855
  });
2700
2856
  }
2701
2857
  });
@@ -2704,15 +2860,15 @@ var removeLinkInner = (from, to, changes, state2) => {
2704
2860
  }
2705
2861
  });
2706
2862
  };
2707
- var removeLink = ({ state: state2, dispatch }) => {
2863
+ var removeLink = ({ state, dispatch }) => {
2708
2864
  const changes = [];
2709
- for (const { from, to } of state2.selection.ranges) {
2710
- removeLinkInner(from, to, changes, state2);
2865
+ for (const { from, to } of state.selection.ranges) {
2866
+ removeLinkInner(from, to, changes, state);
2711
2867
  }
2712
2868
  if (!changes) {
2713
2869
  return false;
2714
2870
  }
2715
- dispatch(state2.update({
2871
+ dispatch(state.update({
2716
2872
  changes,
2717
2873
  userEvent: "format.link.remove",
2718
2874
  scrollIntoView: true
@@ -2720,17 +2876,17 @@ var removeLink = ({ state: state2, dispatch }) => {
2720
2876
  return true;
2721
2877
  };
2722
2878
  var addLink = ({ url, image: image2 } = {}) => {
2723
- return ({ state: state2, dispatch }) => {
2724
- const changes = state2.changeByRange((range) => {
2879
+ return ({ state, dispatch }) => {
2880
+ const changes = state.changeByRange((range) => {
2725
2881
  let { from, to } = range;
2726
2882
  const cutStyles = [];
2727
2883
  let okay = null;
2728
- syntaxTree2(state2).iterate({
2884
+ syntaxTree2(state).iterate({
2729
2885
  from,
2730
2886
  to,
2731
2887
  enter: (node) => {
2732
2888
  if (Object.hasOwn(Textblocks, node.name)) {
2733
- okay = Textblocks[node.name] !== "codeblock" && from >= blockContentStart(node) && to <= blockContentEnd(node, state2.doc);
2889
+ okay = Textblocks[node.name] !== "codeblock" && from >= blockContentStart(node) && to <= blockContentEnd(node, state.doc);
2734
2890
  } else if (Object.hasOwn(InlineMarker, node.name)) {
2735
2891
  const sNode = node.node;
2736
2892
  if (node.from < from && node.to <= to) {
@@ -2750,7 +2906,7 @@ var addLink = ({ url, image: image2 } = {}) => {
2750
2906
  }
2751
2907
  });
2752
2908
  if (okay === null) {
2753
- const line = state2.doc.lineAt(from);
2909
+ const line = state.doc.lineAt(from);
2754
2910
  okay = to <= line.to && !/\S/.test(line.text.slice(from - line.from));
2755
2911
  }
2756
2912
  if (!okay) {
@@ -2760,26 +2916,26 @@ var addLink = ({ url, image: image2 } = {}) => {
2760
2916
  }
2761
2917
  const changes2 = [];
2762
2918
  const changesAfter = [];
2763
- removeLinkInner(from, to, changesAfter, state2);
2919
+ removeLinkInner(from, to, changesAfter, state);
2764
2920
  let cursorOffset = 1;
2765
2921
  for (const style of cutStyles) {
2766
2922
  const type = InlineMarker[style.name];
2767
2923
  const mark = inlineMarkerText(type);
2768
2924
  if (style.from < from) {
2769
2925
  changes2.push({
2770
- from: skipSpaces(from, state2.doc, -1),
2926
+ from: skipSpaces(from, state.doc, -1),
2771
2927
  insert: mark
2772
2928
  });
2773
2929
  changesAfter.push({
2774
- from: skipSpaces(from, state2.doc, 1, to),
2930
+ from: skipSpaces(from, state.doc, 1, to),
2775
2931
  insert: mark
2776
2932
  });
2777
2933
  } else {
2778
2934
  changes2.push({
2779
- from: skipSpaces(to, state2.doc, -1, from),
2935
+ from: skipSpaces(to, state.doc, -1, from),
2780
2936
  insert: mark
2781
2937
  });
2782
- const after = skipSpaces(to, state2.doc, 1);
2938
+ const after = skipSpaces(to, state.doc, 1);
2783
2939
  if (after === to) {
2784
2940
  cursorOffset += mark.length;
2785
2941
  }
@@ -2796,7 +2952,7 @@ var addLink = ({ url, image: image2 } = {}) => {
2796
2952
  from: to,
2797
2953
  insert: `](${url ?? ""})`
2798
2954
  });
2799
- const changeSet = state2.changes(changes2.concat(changesAfter));
2955
+ const changeSet = state.changes(changes2.concat(changesAfter));
2800
2956
  return {
2801
2957
  changes: changeSet,
2802
2958
  range: EditorSelection.cursor(changeSet.mapPos(to, 1) - cursorOffset - (url ? url.length + 2 : 0))
@@ -2805,7 +2961,7 @@ var addLink = ({ url, image: image2 } = {}) => {
2805
2961
  if (changes.changes.empty) {
2806
2962
  return false;
2807
2963
  }
2808
- dispatch(state2.update(changes, {
2964
+ dispatch(state.update(changes, {
2809
2965
  userEvent: "format.link.add",
2810
2966
  scrollIntoView: true
2811
2967
  }));
@@ -2813,14 +2969,14 @@ var addLink = ({ url, image: image2 } = {}) => {
2813
2969
  };
2814
2970
  };
2815
2971
  var addList = (type) => {
2816
- return ({ state: state2, dispatch }) => {
2972
+ return ({ state, dispatch }) => {
2817
2973
  let lastBlock = -1;
2818
2974
  let counter = 1;
2819
2975
  let first = true;
2820
2976
  let parentColumn = null;
2821
2977
  const blocks = [];
2822
- for (const { from, to } of state2.selection.ranges) {
2823
- syntaxTree2(state2).iterate({
2978
+ for (const { from, to } of state.selection.ranges) {
2979
+ syntaxTree2(state).iterate({
2824
2980
  from,
2825
2981
  to,
2826
2982
  enter: (node) => {
@@ -2832,7 +2988,7 @@ var addList = (type) => {
2832
2988
  }
2833
2989
  if (before?.name === (type === 0 ? "OrderedList" : "BulletList")) {
2834
2990
  const item = before.lastChild;
2835
- const itemLine = state2.doc.lineAt(item.from);
2991
+ const itemLine = state.doc.lineAt(item.from);
2836
2992
  const itemText = itemLine.text.slice(item.from - itemLine.from);
2837
2993
  parentColumn = item.from - itemLine.from + /^\s*/.exec(itemText)[0].length;
2838
2994
  if (type === 0) {
@@ -2867,10 +3023,10 @@ var addList = (type) => {
2867
3023
  });
2868
3024
  }
2869
3025
  if (!blocks.length) {
2870
- const { from, to } = state2.doc.lineAt(state2.selection.main.anchor);
3026
+ const { from, to } = state.doc.lineAt(state.selection.main.anchor);
2871
3027
  if (from === to) {
2872
3028
  const insert = type === 1 ? "- " : type === 0 ? "1. " : "- [ ] ";
2873
- dispatch(state2.update({
3029
+ dispatch(state.update({
2874
3030
  changes: [
2875
3031
  {
2876
3032
  from,
@@ -2891,11 +3047,11 @@ var addList = (type) => {
2891
3047
  for (let i = 0; i < blocks.length; i++) {
2892
3048
  const { node, counter: counter2, parentColumn: parentColumn2 } = blocks[i];
2893
3049
  const nodeFrom = node.name === "CodeBlock" ? node.from - 4 : node.from;
2894
- let padding = nodeFrom > 0 && !/\s/.test(state2.doc.sliceString(nodeFrom - 1, nodeFrom)) ? 1 : 0;
3050
+ let padding = nodeFrom > 0 && !/\s/.test(state.doc.sliceString(nodeFrom - 1, nodeFrom)) ? 1 : 0;
2895
3051
  if (type === 0) {
2896
3052
  padding += String(counter2).length;
2897
3053
  }
2898
- let line = state2.doc.lineAt(nodeFrom);
3054
+ let line = state.doc.lineAt(nodeFrom);
2899
3055
  const column = nodeFrom - line.from;
2900
3056
  if (parentColumn2 !== null && parentColumn2 > column) {
2901
3057
  padding = Math.max(padding, parentColumn2 - column);
@@ -2920,7 +3076,7 @@ var addList = (type) => {
2920
3076
  insert: mark
2921
3077
  });
2922
3078
  while (line.to < node.to) {
2923
- line = state2.doc.lineAt(line.to + 1);
3079
+ line = state.doc.lineAt(line.to + 1);
2924
3080
  const open = /^[\s>]*/.exec(line.text)[0].length;
2925
3081
  changes.push({
2926
3082
  from: line.from + Math.min(open, column),
@@ -2935,13 +3091,13 @@ var addList = (type) => {
2935
3091
  next = next.nextSibling;
2936
3092
  }
2937
3093
  if (next?.name === "OrderedList") {
2938
- renumberListItems(next.firstChild, last.counter + 1, changes, state2.doc);
3094
+ renumberListItems(next.firstChild, last.counter + 1, changes, state.doc);
2939
3095
  }
2940
3096
  }
2941
- const changeSet = state2.changes(changes);
2942
- dispatch(state2.update({
3097
+ const changeSet = state.changes(changes);
3098
+ dispatch(state.update({
2943
3099
  changes: changeSet,
2944
- selection: state2.selection.map(changeSet, 1),
3100
+ selection: state.selection.map(changeSet, 1),
2945
3101
  userEvent: "format.list.add",
2946
3102
  scrollIntoView: true
2947
3103
  }));
@@ -2949,13 +3105,13 @@ var addList = (type) => {
2949
3105
  };
2950
3106
  };
2951
3107
  var removeList = (type) => {
2952
- return ({ state: state2, dispatch }) => {
3108
+ return ({ state, dispatch }) => {
2953
3109
  let lastBlock = -1;
2954
3110
  const changes = [];
2955
3111
  const stack = [];
2956
3112
  const targetNodeType = type === 0 ? "OrderedList" : type === 1 ? "BulletList" : "TaskList";
2957
- for (const { from, to } of state2.selection.ranges) {
2958
- syntaxTree2(state2).iterate({
3113
+ for (const { from, to } of state.selection.ranges) {
3114
+ syntaxTree2(state).iterate({
2959
3115
  from,
2960
3116
  to,
2961
3117
  enter: (node) => {
@@ -2972,7 +3128,7 @@ var removeList = (type) => {
2972
3128
  stack.pop();
2973
3129
  } else if (name === "ListItem" && stack[stack.length - 1] === targetNodeType && node.from !== lastBlock) {
2974
3130
  lastBlock = node.from;
2975
- let line = state2.doc.lineAt(node.from);
3131
+ let line = state.doc.lineAt(node.from);
2976
3132
  const mark = /^\s*(\d+[.)] |[-*+] (\[[ x]\] )?)/.exec(line.text.slice(node.from - line.from));
2977
3133
  if (!mark) {
2978
3134
  return false;
@@ -2983,7 +3139,7 @@ var removeList = (type) => {
2983
3139
  to: node.from + mark[0].length
2984
3140
  });
2985
3141
  while (line.to < node.to) {
2986
- line = state2.doc.lineAt(line.to + 1);
3142
+ line = state.doc.lineAt(line.to + 1);
2987
3143
  const open = /^[\s>]*/.exec(line.text)[0].length;
2988
3144
  if (open > column) {
2989
3145
  changes.push({
@@ -2993,7 +3149,7 @@ var removeList = (type) => {
2993
3149
  }
2994
3150
  }
2995
3151
  if (node.to >= to) {
2996
- renumberListItems(node.node.nextSibling, 1, changes, state2.doc);
3152
+ renumberListItems(node.node.nextSibling, 1, changes, state.doc);
2997
3153
  }
2998
3154
  return false;
2999
3155
  }
@@ -3003,7 +3159,7 @@ var removeList = (type) => {
3003
3159
  if (!changes.length) {
3004
3160
  return false;
3005
3161
  }
3006
- dispatch(state2.update({
3162
+ dispatch(state.update({
3007
3163
  changes,
3008
3164
  userEvent: "format.list.remove",
3009
3165
  scrollIntoView: true
@@ -3037,12 +3193,12 @@ var renumberListItems = (item, counter, changes, doc) => {
3037
3193
  }
3038
3194
  };
3039
3195
  var setBlockquote = (enable) => {
3040
- return ({ state: state2, dispatch }) => {
3196
+ return ({ state, dispatch }) => {
3041
3197
  const lines = [];
3042
3198
  let lastBlock = -1;
3043
- for (const { from, to } of state2.selection.ranges) {
3199
+ for (const { from, to } of state.selection.ranges) {
3044
3200
  const sawBlock = false;
3045
- syntaxTree2(state2).iterate({
3201
+ syntaxTree2(state).iterate({
3046
3202
  from,
3047
3203
  to,
3048
3204
  enter: (node) => {
@@ -3051,9 +3207,9 @@ var setBlockquote = (enable) => {
3051
3207
  return false;
3052
3208
  }
3053
3209
  lastBlock = node.from;
3054
- let line2 = state2.doc.lineAt(node.from);
3210
+ let line2 = state.doc.lineAt(node.from);
3055
3211
  if (line2.number > 1) {
3056
- const prevLine = state2.doc.line(line2.number - 1);
3212
+ const prevLine = state.doc.line(line2.number - 1);
3057
3213
  if (/^[>\s]*$/.test(prevLine.text)) {
3058
3214
  if (!enable || lines.length && lines[lines.length - 1].number === prevLine.number - 1) {
3059
3215
  lines.push(prevLine);
@@ -3065,10 +3221,10 @@ var setBlockquote = (enable) => {
3065
3221
  if (line2.to >= node.to) {
3066
3222
  break;
3067
3223
  }
3068
- line2 = state2.doc.line(line2.number + 1);
3224
+ line2 = state.doc.line(line2.number + 1);
3069
3225
  }
3070
- if (!enable && line2.number < state2.doc.lines) {
3071
- const nextLine = state2.doc.line(line2.number + 1);
3226
+ if (!enable && line2.number < state.doc.lines) {
3227
+ const nextLine = state.doc.line(line2.number + 1);
3072
3228
  if (/^[>\s]*$/.test(nextLine.text)) {
3073
3229
  lines.push(nextLine);
3074
3230
  }
@@ -3078,7 +3234,7 @@ var setBlockquote = (enable) => {
3078
3234
  }
3079
3235
  });
3080
3236
  let line;
3081
- if (!sawBlock && enable && from === to && !/\S/.test((line = state2.doc.lineAt(from)).text)) {
3237
+ if (!sawBlock && enable && from === to && !/\S/.test((line = state.doc.lineAt(from)).text)) {
3082
3238
  lines.push(line);
3083
3239
  }
3084
3240
  }
@@ -3102,10 +3258,10 @@ var setBlockquote = (enable) => {
3102
3258
  if (!changes.length) {
3103
3259
  return false;
3104
3260
  }
3105
- const changeSet = state2.changes(changes);
3106
- dispatch(state2.update({
3261
+ const changeSet = state.changes(changes);
3262
+ dispatch(state.update({
3107
3263
  changes: changeSet,
3108
- selection: state2.selection.map(changeSet, 1),
3264
+ selection: state.selection.map(changeSet, 1),
3109
3265
  userEvent: enable ? "format.blockquote.add" : "format.blockquote.remove",
3110
3266
  scrollIntoView: true
3111
3267
  }));
@@ -3118,11 +3274,11 @@ var toggleBlockquote = (target) => {
3118
3274
  return (getFormatting(target.state).blockQuote ? removeBlockquote : addBlockquote)(target);
3119
3275
  };
3120
3276
  var addCodeblock = (target) => {
3121
- const { state: state2, dispatch } = target;
3122
- const { selection } = state2;
3277
+ const { state, dispatch } = target;
3278
+ const { selection } = state;
3123
3279
  if (selection.ranges.length === 1 && selection.main.empty) {
3124
3280
  const { head } = selection.main;
3125
- const line = state2.doc.lineAt(head);
3281
+ const line = state.doc.lineAt(head);
3126
3282
  if (!/\S/.test(line.text) && head === line.from) {
3127
3283
  snippets.codeblock(target, null, line.from, line.to);
3128
3284
  return true;
@@ -3132,7 +3288,7 @@ var addCodeblock = (target) => {
3132
3288
  for (const { from, to } of selection.ranges) {
3133
3289
  let blockFrom = from;
3134
3290
  let blockTo = to;
3135
- syntaxTree2(state2).iterate({
3291
+ syntaxTree2(state).iterate({
3136
3292
  from,
3137
3293
  to,
3138
3294
  enter: (node) => {
@@ -3141,8 +3297,8 @@ var addCodeblock = (target) => {
3141
3297
  blockFrom = node.from;
3142
3298
  blockTo = node.to;
3143
3299
  } else {
3144
- blockFrom = Math.min(blockFrom, state2.doc.lineAt(node.from).from);
3145
- blockTo = Math.max(blockTo, state2.doc.lineAt(node.to).to);
3300
+ blockFrom = Math.min(blockFrom, state.doc.lineAt(node.from).from);
3301
+ blockTo = Math.max(blockTo, state.doc.lineAt(node.to).to);
3146
3302
  }
3147
3303
  }
3148
3304
  }
@@ -3160,7 +3316,7 @@ var addCodeblock = (target) => {
3160
3316
  return false;
3161
3317
  }
3162
3318
  const changes = ranges.map(({ from, to }) => {
3163
- const column = from - state2.doc.lineAt(from).from;
3319
+ const column = from - state.doc.lineAt(from).from;
3164
3320
  return [
3165
3321
  {
3166
3322
  from,
@@ -3172,30 +3328,30 @@ var addCodeblock = (target) => {
3172
3328
  }
3173
3329
  ];
3174
3330
  });
3175
- dispatch(state2.update({
3331
+ dispatch(state.update({
3176
3332
  changes,
3177
3333
  userEvent: "format.codeblock.add",
3178
3334
  scrollIntoView: true
3179
3335
  }));
3180
3336
  return true;
3181
3337
  };
3182
- var removeCodeblock = ({ state: state2, dispatch }) => {
3338
+ var removeCodeblock = ({ state, dispatch }) => {
3183
3339
  let lastBlock = -1;
3184
3340
  const changes = [];
3185
- for (const { from, to } of state2.selection.ranges) {
3186
- syntaxTree2(state2).iterate({
3341
+ for (const { from, to } of state.selection.ranges) {
3342
+ syntaxTree2(state).iterate({
3187
3343
  from,
3188
3344
  to,
3189
3345
  enter: (node) => {
3190
3346
  if (Textblocks[node.name] === "codeblock" && lastBlock !== node.from) {
3191
3347
  lastBlock = node.from;
3192
- const firstLine = state2.doc.lineAt(node.from);
3348
+ const firstLine = state.doc.lineAt(node.from);
3193
3349
  if (node.name === "FencedCode") {
3194
3350
  changes.push({
3195
3351
  from: node.from,
3196
3352
  to: firstLine.to + 1 + node.from - firstLine.from
3197
3353
  });
3198
- const lastLine = state2.doc.lineAt(node.to);
3354
+ const lastLine = state.doc.lineAt(node.to);
3199
3355
  if (/^([\s>]|[-*+] |\d+[).])*`+$/.test(lastLine.text)) {
3200
3356
  changes.push({
3201
3357
  from: lastLine.from - (lastLine.number === firstLine.number + 1 ? 0 : 1),
@@ -3204,7 +3360,7 @@ var removeCodeblock = ({ state: state2, dispatch }) => {
3204
3360
  }
3205
3361
  } else {
3206
3362
  const column = node.from - firstLine.from;
3207
- for (let line = firstLine; ; line = state2.doc.line(line.number + 1)) {
3363
+ for (let line = firstLine; ; line = state.doc.line(line.number + 1)) {
3208
3364
  changes.push({
3209
3365
  from: line.from + column - 4,
3210
3366
  to: line.from + column
@@ -3221,7 +3377,7 @@ var removeCodeblock = ({ state: state2, dispatch }) => {
3221
3377
  if (!changes.length) {
3222
3378
  return false;
3223
3379
  }
3224
- dispatch(state2.update({
3380
+ dispatch(state.update({
3225
3381
  changes,
3226
3382
  userEvent: "format.codeblock.remove",
3227
3383
  scrollIntoView: true
@@ -3233,7 +3389,7 @@ var toggleCodeblock = (target) => {
3233
3389
  };
3234
3390
  var formattingKeymap = (_options = {}) => {
3235
3391
  return [
3236
- keymap6.of([
3392
+ keymap7.of([
3237
3393
  {
3238
3394
  key: "meta-b",
3239
3395
  run: toggleStrong
@@ -3284,7 +3440,7 @@ var Textblocks = {
3284
3440
  TableCell: "tablecell",
3285
3441
  Task: "paragraph"
3286
3442
  };
3287
- var getFormatting = (state2) => {
3443
+ var getFormatting = (state) => {
3288
3444
  let blockType = null;
3289
3445
  const inline = [
3290
3446
  null,
@@ -3310,7 +3466,7 @@ var getFormatting = (state2) => {
3310
3466
  continue;
3311
3467
  } else if (currentBlock.active[i]) {
3312
3468
  inline[i] = true;
3313
- } else if (/\S/.test(state2.doc.sliceString(currentBlock.pos, upto))) {
3469
+ } else if (/\S/.test(state.doc.sliceString(currentBlock.pos, upto))) {
3314
3470
  inline[i] = false;
3315
3471
  }
3316
3472
  }
@@ -3321,12 +3477,12 @@ var getFormatting = (state2) => {
3321
3477
  currentBlock.pos = Math.min(upto, currentBlock.end);
3322
3478
  }
3323
3479
  };
3324
- const { selection } = state2;
3480
+ const { selection } = state;
3325
3481
  for (const range of selection.ranges) {
3326
3482
  if (range.empty && inline.some((v) => v === null)) {
3327
3483
  const contextSize = Math.min(range.head, 6);
3328
- const contextBefore = state2.doc.sliceString(range.head - contextSize, range.head);
3329
- let contextAfter = state2.doc.sliceString(range.head, range.head + contextSize);
3484
+ const contextBefore = state.doc.sliceString(range.head - contextSize, range.head);
3485
+ let contextAfter = state.doc.sliceString(range.head, range.head + contextSize);
3330
3486
  for (let i = 0; i < contextSize; i++) {
3331
3487
  const ch = contextAfter[i];
3332
3488
  if (ch !== contextBefore[contextBefore.length - 1 - i] || !/[~`*]/.test(ch)) {
@@ -3345,7 +3501,7 @@ var getFormatting = (state2) => {
3345
3501
  }
3346
3502
  }
3347
3503
  }
3348
- syntaxTree2(state2).iterate({
3504
+ syntaxTree2(state).iterate({
3349
3505
  from: range.from,
3350
3506
  to: range.to,
3351
3507
  enter: (node) => {
@@ -3419,7 +3575,7 @@ var getFormatting = (state2) => {
3419
3575
  }
3420
3576
  });
3421
3577
  }
3422
- const { from, to } = state2.doc.lineAt(selection.main.anchor);
3578
+ const { from, to } = state.doc.lineAt(selection.main.anchor);
3423
3579
  const blankLine = from === to;
3424
3580
  return {
3425
3581
  blankLine,
@@ -3434,8 +3590,8 @@ var getFormatting = (state2) => {
3434
3590
  };
3435
3591
  };
3436
3592
  var useFormattingState = () => {
3437
- const [state2, setState] = useState2();
3438
- const observer = useMemo2(() => EditorView12.updateListener.of((update2) => {
3593
+ const [state, setState] = useState2();
3594
+ const observer = useMemo2(() => EditorView14.updateListener.of((update2) => {
3439
3595
  if (update2.docChanged || update2.selectionSet) {
3440
3596
  setState((prevState) => {
3441
3597
  const newState = getFormatting(update2.state);
@@ -3447,7 +3603,7 @@ var useFormattingState = () => {
3447
3603
  }
3448
3604
  }), []);
3449
3605
  return [
3450
- state2,
3606
+ state,
3451
3607
  observer
3452
3608
  ];
3453
3609
  };
@@ -3508,7 +3664,7 @@ import { markdownLanguage as markdownLanguage3, markdown } from "@codemirror/lan
3508
3664
  import { syntaxHighlighting as syntaxHighlighting2 } from "@codemirror/language";
3509
3665
  import { languages } from "@codemirror/language-data";
3510
3666
  import { lintKeymap } from "@codemirror/lint";
3511
- import { keymap as keymap7 } from "@codemirror/view";
3667
+ import { keymap as keymap8 } from "@codemirror/view";
3512
3668
 
3513
3669
  // packages/ui/react-ui-editor/src/extensions/markdown/highlight.ts
3514
3670
  import { markdownLanguage as markdownLanguage2 } from "@codemirror/lang-markdown";
@@ -3714,7 +3870,7 @@ var createMarkdownExtensions = ({ themeMode } = {}) => {
3714
3870
  }),
3715
3871
  // Custom styles.
3716
3872
  syntaxHighlighting2(markdownHighlightStyle()),
3717
- keymap7.of([
3873
+ keymap8.of([
3718
3874
  // https://codemirror.net/docs/ref/#commands.indentWithTab
3719
3875
  indentWithTab2,
3720
3876
  // https://codemirror.net/docs/ref/#commands.defaultKeymap
@@ -3727,18 +3883,18 @@ var createMarkdownExtensions = ({ themeMode } = {}) => {
3727
3883
 
3728
3884
  // packages/ui/react-ui-editor/src/extensions/markdown/debug.ts
3729
3885
  import { syntaxTree as syntaxTree3 } from "@codemirror/language";
3730
- import { StateField as StateField6 } from "@codemirror/state";
3731
- var debugTree = (cb) => StateField6.define({
3732
- create: (state2) => cb(convertTreeToJson(state2)),
3886
+ import { StateField as StateField7 } from "@codemirror/state";
3887
+ var debugTree = (cb) => StateField7.define({
3888
+ create: (state) => cb(convertTreeToJson(state)),
3733
3889
  update: (value, tr) => cb(convertTreeToJson(tr.state))
3734
3890
  });
3735
- var convertTreeToJson = (state2) => {
3891
+ var convertTreeToJson = (state) => {
3736
3892
  const treeToJson = (cursor) => {
3737
3893
  const node = {
3738
3894
  type: cursor.type.name,
3739
3895
  from: cursor.from,
3740
3896
  to: cursor.to,
3741
- text: state2.doc.slice(cursor.from, cursor.to).toString(),
3897
+ text: state.doc.slice(cursor.from, cursor.to).toString(),
3742
3898
  children: []
3743
3899
  };
3744
3900
  if (cursor.firstChild()) {
@@ -3749,19 +3905,19 @@ var convertTreeToJson = (state2) => {
3749
3905
  }
3750
3906
  return node;
3751
3907
  };
3752
- return treeToJson(syntaxTree3(state2).cursor());
3908
+ return treeToJson(syntaxTree3(state).cursor());
3753
3909
  };
3754
3910
 
3755
3911
  // packages/ui/react-ui-editor/src/extensions/markdown/decorate.ts
3756
3912
  import { syntaxTree as syntaxTree7 } from "@codemirror/language";
3757
- import { RangeSetBuilder as RangeSetBuilder3, StateEffect as StateEffect4 } from "@codemirror/state";
3758
- import { EditorView as EditorView16, Decoration as Decoration7, WidgetType as WidgetType5, ViewPlugin as ViewPlugin6 } from "@codemirror/view";
3759
- import { invariant as invariant3 } from "@dxos/invariant";
3913
+ import { RangeSetBuilder as RangeSetBuilder3, StateEffect as StateEffect5 } from "@codemirror/state";
3914
+ import { EditorView as EditorView18, Decoration as Decoration7, WidgetType as WidgetType5, ViewPlugin as ViewPlugin6 } from "@codemirror/view";
3915
+ import { invariant as invariant4 } from "@dxos/invariant";
3760
3916
  import { mx as mx2 } from "@dxos/react-ui-theme";
3761
3917
 
3762
3918
  // packages/ui/react-ui-editor/src/extensions/markdown/changes.ts
3763
3919
  import { syntaxTree as syntaxTree4 } from "@codemirror/language";
3764
- import { Transaction } from "@codemirror/state";
3920
+ import { Transaction as Transaction2 } from "@codemirror/state";
3765
3921
  import { ViewPlugin as ViewPlugin5 } from "@codemirror/view";
3766
3922
  var adjustChanges = () => {
3767
3923
  return ViewPlugin5.fromClass(class {
@@ -3769,7 +3925,7 @@ var adjustChanges = () => {
3769
3925
  const tree = syntaxTree4(update2.state);
3770
3926
  const adjustments = [];
3771
3927
  for (const tr of update2.transactions) {
3772
- const event = tr.annotation(Transaction.userEvent);
3928
+ const event = tr.annotation(Transaction2.userEvent);
3773
3929
  switch (event) {
3774
3930
  //
3775
3931
  // Enter
@@ -3905,36 +4061,38 @@ var getValidUrl = (str) => {
3905
4061
 
3906
4062
  // packages/ui/react-ui-editor/src/extensions/markdown/image.ts
3907
4063
  import { syntaxTree as syntaxTree5 } from "@codemirror/language";
3908
- import { StateField as StateField7 } from "@codemirror/state";
3909
- import { Decoration as Decoration5, EditorView as EditorView13, WidgetType as WidgetType3 } from "@codemirror/view";
4064
+ import { StateField as StateField8 } from "@codemirror/state";
4065
+ import { Decoration as Decoration5, EditorView as EditorView15, WidgetType as WidgetType3 } from "@codemirror/view";
3910
4066
  var image = (_options = {}) => {
3911
- return StateField7.define({
3912
- create: (state2) => {
3913
- return Decoration5.set(buildDecorations(0, state2.doc.length, state2));
3914
- },
3915
- update: (value, tr) => {
3916
- if (!tr.docChanged && !tr.selection) {
3917
- return value;
3918
- }
3919
- const cursor = tr.state.selection.main.head;
3920
- const oldCursor = tr.changes.mapPos(tr.startState.selection.main.head);
3921
- let from = Math.min(cursor, oldCursor);
3922
- let to = Math.max(cursor, oldCursor);
3923
- tr.changes.iterChangedRanges((fromA, toA, fromB, toB) => {
3924
- from = Math.min(from, fromB);
3925
- to = Math.max(to, toB);
3926
- });
3927
- from = tr.state.doc.lineAt(from).from;
3928
- to = tr.state.doc.lineAt(to).to;
3929
- return value.map(tr.changes).update({
3930
- filterFrom: from,
3931
- filterTo: to,
3932
- filter: () => false,
3933
- add: buildDecorations(from, to, tr.state)
3934
- });
3935
- },
3936
- provide: (field) => EditorView13.decorations.from(field)
3937
- });
4067
+ return [
4068
+ StateField8.define({
4069
+ create: (state) => {
4070
+ return Decoration5.set(buildDecorations(0, state.doc.length, state));
4071
+ },
4072
+ update: (value, tr) => {
4073
+ if (!tr.docChanged && !tr.selection) {
4074
+ return value;
4075
+ }
4076
+ const cursor = tr.state.selection.main.head;
4077
+ const oldCursor = tr.changes.mapPos(tr.startState.selection.main.head);
4078
+ let from = Math.min(cursor, oldCursor);
4079
+ let to = Math.max(cursor, oldCursor);
4080
+ tr.changes.iterChangedRanges((fromA, toA, fromB, toB) => {
4081
+ from = Math.min(from, fromB);
4082
+ to = Math.max(to, toB);
4083
+ });
4084
+ from = tr.state.doc.lineAt(from).from;
4085
+ to = tr.state.doc.lineAt(to).to;
4086
+ return value.map(tr.changes).update({
4087
+ filterFrom: from,
4088
+ filterTo: to,
4089
+ filter: () => false,
4090
+ add: buildDecorations(from, to, tr.state)
4091
+ });
4092
+ },
4093
+ provide: (field) => EditorView15.decorations.from(field)
4094
+ })
4095
+ ];
3938
4096
  };
3939
4097
  var preloaded = /* @__PURE__ */ new Set();
3940
4098
  var preloadImage = (url) => {
@@ -3944,16 +4102,19 @@ var preloadImage = (url) => {
3944
4102
  preloaded.add(url);
3945
4103
  }
3946
4104
  };
3947
- var buildDecorations = (from, to, state2) => {
4105
+ var buildDecorations = (from, to, state) => {
3948
4106
  const decorations = [];
3949
- const cursor = state2.selection.main.head;
3950
- syntaxTree5(state2).iterate({
4107
+ const cursor = state.selection.main.head;
4108
+ syntaxTree5(state).iterate({
3951
4109
  enter: (node) => {
3952
4110
  if (node.name === "Image") {
3953
4111
  const urlNode = node.node.getChild("URL");
3954
4112
  if (urlNode) {
3955
- const hide2 = state2.readOnly || cursor < node.from || cursor > node.to;
3956
- const url = state2.sliceDoc(urlNode.from, urlNode.to);
4113
+ const hide2 = state.readOnly || cursor < node.from || cursor > node.to || !state.field(focusField);
4114
+ const url = state.sliceDoc(urlNode.from, urlNode.to);
4115
+ if (url.match(/^https?:\/\//) === null && url.match(/^file?:\/\//) === null) {
4116
+ return;
4117
+ }
3957
4118
  preloadImage(url);
3958
4119
  decorations.push(Decoration5.replace({
3959
4120
  block: true,
@@ -3979,18 +4140,20 @@ var ImageWidget = class extends WidgetType3 {
3979
4140
  const img = document.createElement("img");
3980
4141
  img.setAttribute("src", this._url);
3981
4142
  img.setAttribute("class", "cm-image");
3982
- img.onload = () => img.classList.add("cm-loaded-image");
4143
+ if (view.state.field(focusField)) {
4144
+ img.onload = () => img.classList.add("cm-loaded-image");
4145
+ } else {
4146
+ img.classList.add("cm-loaded-image");
4147
+ }
3983
4148
  return img;
3984
4149
  }
3985
4150
  };
3986
- var imageUpload = (options = {}) => {
3987
- };
3988
4151
 
3989
4152
  // packages/ui/react-ui-editor/src/extensions/markdown/styles.ts
3990
- import { EditorView as EditorView14 } from "@codemirror/view";
4153
+ import { EditorView as EditorView16 } from "@codemirror/view";
3991
4154
  var bulletListIndentationWidth = 24;
3992
4155
  var orderedListIndentationWidth = 36;
3993
- var formattingStyles = EditorView14.theme({
4156
+ var formattingStyles = EditorView16.theme({
3994
4157
  /**
3995
4158
  * Horizontal rule.
3996
4159
  */
@@ -4089,25 +4252,25 @@ var formattingStyles = EditorView14.theme({
4089
4252
 
4090
4253
  // packages/ui/react-ui-editor/src/extensions/markdown/table.ts
4091
4254
  import { syntaxTree as syntaxTree6 } from "@codemirror/language";
4092
- import { RangeSetBuilder as RangeSetBuilder2, StateField as StateField8 } from "@codemirror/state";
4093
- import { Decoration as Decoration6, EditorView as EditorView15, WidgetType as WidgetType4 } from "@codemirror/view";
4255
+ import { RangeSetBuilder as RangeSetBuilder2, StateField as StateField9 } from "@codemirror/state";
4256
+ import { Decoration as Decoration6, EditorView as EditorView17, WidgetType as WidgetType4 } from "@codemirror/view";
4094
4257
  var table = (options = {}) => {
4095
- return StateField8.define({
4096
- create: (state2) => update(state2, options),
4258
+ return StateField9.define({
4259
+ create: (state) => update(state, options),
4097
4260
  update: (_, tr) => update(tr.state, options),
4098
- provide: (field) => EditorView15.decorations.from(field)
4261
+ provide: (field) => EditorView17.decorations.from(field)
4099
4262
  });
4100
4263
  };
4101
- var update = (state2, _options) => {
4264
+ var update = (state, _options) => {
4102
4265
  const builder = new RangeSetBuilder2();
4103
- const cursor = state2.selection.main.head;
4266
+ const cursor = state.selection.main.head;
4104
4267
  const tables = [];
4105
4268
  const getTable = () => tables[tables.length - 1];
4106
4269
  const getRow = () => {
4107
4270
  const table2 = getTable();
4108
4271
  return table2.rows?.[table2.rows.length - 1];
4109
4272
  };
4110
- syntaxTree6(state2).iterate({
4273
+ syntaxTree6(state).iterate({
4111
4274
  enter: (node) => {
4112
4275
  switch (node.name) {
4113
4276
  case "Table": {
@@ -4128,9 +4291,9 @@ var update = (state2, _options) => {
4128
4291
  case "TableCell": {
4129
4292
  const row = getRow();
4130
4293
  if (row) {
4131
- row.push(state2.sliceDoc(node.from, node.to));
4294
+ row.push(state.sliceDoc(node.from, node.to));
4132
4295
  } else {
4133
- getTable().header?.push(state2.sliceDoc(node.from, node.to));
4296
+ getTable().header?.push(state.sliceDoc(node.from, node.to));
4134
4297
  }
4135
4298
  break;
4136
4299
  }
@@ -4138,7 +4301,7 @@ var update = (state2, _options) => {
4138
4301
  }
4139
4302
  });
4140
4303
  tables.forEach((table2) => {
4141
- const replace = state2.readOnly || cursor < table2.from || cursor > table2.to;
4304
+ const replace = state.readOnly || cursor < table2.from || cursor > table2.to;
4142
4305
  if (replace) {
4143
4306
  builder.add(table2.from, table2.to, Decoration6.replace({
4144
4307
  block: true,
@@ -4302,9 +4465,9 @@ var checkedTask = Decoration7.replace({
4302
4465
  var uncheckedTask = Decoration7.replace({
4303
4466
  widget: new CheckboxWidget(false)
4304
4467
  });
4305
- var editingRange = (state2, range, focus) => {
4306
- const { readOnly, selection: { main: { head } } } = state2;
4307
- return focus && !readOnly && head >= range.from && head <= range.to;
4468
+ var editingRange = (state, range, focus2) => {
4469
+ const { readOnly, selection: { main: { head } } } = state;
4470
+ return focus2 && !readOnly && head >= range.from && head <= range.to;
4308
4471
  };
4309
4472
  var autoHideTags = /* @__PURE__ */ new Set([
4310
4473
  "CodeMark",
@@ -4314,13 +4477,13 @@ var autoHideTags = /* @__PURE__ */ new Set([
4314
4477
  "SubscriptMark",
4315
4478
  "SuperscriptMark"
4316
4479
  ]);
4317
- var buildDecorations2 = (view, options, focus) => {
4480
+ var buildDecorations2 = (view, options, focus2) => {
4318
4481
  const deco = new RangeSetBuilder3();
4319
4482
  const atomicDeco = new RangeSetBuilder3();
4320
- const { state: state2 } = view;
4483
+ const { state } = view;
4321
4484
  const headerLevels = [];
4322
4485
  const getHeaderLevels = (node, level) => {
4323
- invariant3(level > 0, void 0, {
4486
+ invariant4(level > 0, void 0, {
4324
4487
  F: __dxlog_file9,
4325
4488
  L: 178,
4326
4489
  S: void 0,
@@ -4359,7 +4522,7 @@ var buildDecorations2 = (view, options, focus) => {
4359
4522
  listLevels.pop();
4360
4523
  };
4361
4524
  const getCurrentListLevel = () => {
4362
- invariant3(listLevels.length, void 0, {
4525
+ invariant4(listLevels.length, void 0, {
4363
4526
  F: __dxlog_file9,
4364
4527
  L: 200,
4365
4528
  S: void 0,
@@ -4386,7 +4549,7 @@ var buildDecorations2 = (view, options, focus) => {
4386
4549
  if (options.numberedHeadings?.from !== void 0) {
4387
4550
  headers[level - 1].number++;
4388
4551
  }
4389
- const editing = editingRange(state2, node, focus);
4552
+ const editing = editingRange(state, node, focus2);
4390
4553
  if (editing) {
4391
4554
  break;
4392
4555
  }
@@ -4418,7 +4581,7 @@ var buildDecorations2 = (view, options, focus) => {
4418
4581
  break;
4419
4582
  }
4420
4583
  case "ListItem": {
4421
- const line = state2.doc.lineAt(node.from);
4584
+ const line = state.doc.lineAt(node.from);
4422
4585
  const list = getCurrentListLevel();
4423
4586
  const width = list.type === "OrderedList" ? orderedListIndentationWidth : bulletListIndentationWidth;
4424
4587
  const offset = ((list.level ?? 0) + 1) * width;
@@ -4440,17 +4603,17 @@ var buildDecorations2 = (view, options, focus) => {
4440
4603
  break;
4441
4604
  }
4442
4605
  const label = list.type === "OrderedList" ? `${++list.number}.` : Unicode.bulletSmall;
4443
- const line = state2.doc.lineAt(node.from);
4444
- const to = state2.doc.sliceString(node.to, node.to + 1) === " " ? node.to + 1 : node.to;
4606
+ const line = state.doc.lineAt(node.from);
4607
+ const to = state.doc.sliceString(node.to, node.to + 1) === " " ? node.to + 1 : node.to;
4445
4608
  atomicDeco.add(line.from, to, Decoration7.replace({
4446
4609
  widget: new TextWidget(label, list.type === "OrderedList" ? "cm-list-mark cm-list-mark-ordered" : "cm-list-mark cm-list-mark-bullet")
4447
4610
  }));
4448
4611
  break;
4449
4612
  }
4450
4613
  case "TaskMarker": {
4451
- const checked = state2.doc.sliceString(node.from + 1, node.to - 1) === "x";
4452
- const line = state2.doc.lineAt(node.from);
4453
- const to = state2.doc.sliceString(node.to, node.to + 1) === " " ? node.to + 1 : node.to;
4614
+ const checked = state.doc.sliceString(node.from + 1, node.to - 1) === "x";
4615
+ const line = state.doc.lineAt(node.from);
4616
+ const to = state.doc.sliceString(node.to, node.to + 1) === " " ? node.to + 1 : node.to;
4454
4617
  atomicDeco.add(line.from, to, checked ? checkedTask : uncheckedTask);
4455
4618
  break;
4456
4619
  }
@@ -4458,7 +4621,7 @@ var buildDecorations2 = (view, options, focus) => {
4458
4621
  // Blockquote > QuoteMark > Paragraph
4459
4622
  //
4460
4623
  case "Blockquote": {
4461
- const editing = editingRange(state2, node, focus);
4624
+ const editing = editingRange(state, node, focus2);
4462
4625
  const quoteMark = node.node.getChild("QuoteMark");
4463
4626
  const paragraph = node.node.getChild("Paragraph");
4464
4627
  if (!editing && quoteMark && paragraph) {
@@ -4479,7 +4642,7 @@ var buildDecorations2 = (view, options, focus) => {
4479
4642
  // CommentBlock
4480
4643
  //
4481
4644
  case "CommentBlock": {
4482
- const editing = editingRange(state2, node, focus);
4645
+ const editing = editingRange(state, node, focus2);
4483
4646
  for (const block of view.viewportLineBlocks) {
4484
4647
  if (block.to < node.from) {
4485
4648
  continue;
@@ -4488,7 +4651,7 @@ var buildDecorations2 = (view, options, focus) => {
4488
4651
  break;
4489
4652
  }
4490
4653
  const isFirst = block.from <= node.from;
4491
- const isLast = block.to >= node.to && /^(\s>)*-->$/.test(state2.doc.sliceString(block.from, block.to));
4654
+ const isLast = block.to >= node.to && /^(\s>)*-->$/.test(state.doc.sliceString(block.from, block.to));
4492
4655
  deco.add(block.from, block.from, isFirst ? commentBlockLineFirst : isLast ? commentBlockLineLast : commentBlockLine);
4493
4656
  if (!editing && (isFirst || isLast)) {
4494
4657
  atomicDeco.add(block.from, block.to, hide);
@@ -4508,9 +4671,9 @@ var buildDecorations2 = (view, options, focus) => {
4508
4671
  break;
4509
4672
  }
4510
4673
  const first = block.from <= node.from;
4511
- const last = block.to >= node.to && /^(\s>)*```$/.test(state2.doc.sliceString(block.from, block.to));
4674
+ const last = block.to >= node.to && /^(\s>)*```$/.test(state.doc.sliceString(block.from, block.to));
4512
4675
  deco.add(block.from, block.from, first ? fencedCodeLineFirst : last ? fencedCodeLineLast : fencedCodeLine);
4513
- const editing = editingRange(state2, node, focus);
4676
+ const editing = editingRange(state, node, focus2);
4514
4677
  if (!editing && (first || last)) {
4515
4678
  atomicDeco.add(block.from, block.to, hide);
4516
4679
  }
@@ -4523,9 +4686,9 @@ var buildDecorations2 = (view, options, focus) => {
4523
4686
  case "Link": {
4524
4687
  const marks = node.node.getChildren("LinkMark");
4525
4688
  const urlNode = node.node.getChild("URL");
4526
- const editing = editingRange(state2, node, focus);
4689
+ const editing = editingRange(state, node, focus2);
4527
4690
  if (urlNode && marks.length >= 2) {
4528
- const url = state2.sliceDoc(urlNode.from, urlNode.to);
4691
+ const url = state.sliceDoc(urlNode.from, urlNode.to);
4529
4692
  if (!editing) {
4530
4693
  atomicDeco.add(node.from, marks[0].to, hide);
4531
4694
  }
@@ -4550,14 +4713,14 @@ var buildDecorations2 = (view, options, focus) => {
4550
4713
  // HR
4551
4714
  //
4552
4715
  case "HorizontalRule": {
4553
- if (!editingRange(state2, node, focus)) {
4716
+ if (!editingRange(state, node, focus2)) {
4554
4717
  deco.add(node.from, node.to, horizontalRule);
4555
4718
  }
4556
4719
  break;
4557
4720
  }
4558
4721
  default: {
4559
4722
  if (autoHideTags.has(node.name)) {
4560
- if (!editingRange(state2, node.node.parent, focus)) {
4723
+ if (!editingRange(state, node.node.parent, focus2)) {
4561
4724
  atomicDeco.add(node.from, node.to, hide);
4562
4725
  }
4563
4726
  }
@@ -4573,7 +4736,7 @@ var buildDecorations2 = (view, options, focus) => {
4573
4736
  }
4574
4737
  }
4575
4738
  };
4576
- const tree = syntaxTree7(state2);
4739
+ const tree = syntaxTree7(state);
4577
4740
  if (options.numberedHeadings?.from === void 0) {
4578
4741
  for (const { from, to } of view.visibleRanges) {
4579
4742
  tree.iterate({
@@ -4594,7 +4757,7 @@ var buildDecorations2 = (view, options, focus) => {
4594
4757
  atomicDeco: atomicDeco.finish()
4595
4758
  };
4596
4759
  };
4597
- var forceUpdate = StateEffect4.define();
4760
+ var forceUpdate = StateEffect5.define();
4598
4761
  var decorateMarkdown = (options = {}) => {
4599
4762
  return [
4600
4763
  ViewPlugin6.fromClass(class {
@@ -4629,9 +4792,9 @@ var decorateMarkdown = (options = {}) => {
4629
4792
  }
4630
4793
  }, {
4631
4794
  provide: (plugin) => [
4632
- EditorView16.atomicRanges.of((view) => view.plugin(plugin)?.atomicDeco ?? Decoration7.none),
4633
- EditorView16.decorations.of((view) => view.plugin(plugin)?.atomicDeco ?? Decoration7.none),
4634
- EditorView16.decorations.of((view) => view.plugin(plugin)?.deco ?? Decoration7.none)
4795
+ EditorView18.atomicRanges.of((view) => view.plugin(plugin)?.atomicDeco ?? Decoration7.none),
4796
+ EditorView18.decorations.of((view) => view.plugin(plugin)?.atomicDeco ?? Decoration7.none),
4797
+ EditorView18.decorations.of((view) => view.plugin(plugin)?.deco ?? Decoration7.none)
4635
4798
  ]
4636
4799
  }),
4637
4800
  image(),
@@ -4679,7 +4842,7 @@ var linkTooltip = (render) => {
4679
4842
 
4680
4843
  // packages/ui/react-ui-editor/src/extensions/mention.ts
4681
4844
  import { autocompletion as autocompletion2 } from "@codemirror/autocomplete";
4682
- import { log as log7 } from "@dxos/log";
4845
+ import { log as log6 } from "@dxos/log";
4683
4846
  var __dxlog_file10 = "/home/runner/work/dxos/dxos/packages/ui/react-ui-editor/src/extensions/mention.ts";
4684
4847
  var mention = ({ onSearch }) => {
4685
4848
  return autocompletion2({
@@ -4692,7 +4855,7 @@ var mention = ({ onSearch }) => {
4692
4855
  icons: false,
4693
4856
  override: [
4694
4857
  (context) => {
4695
- log7.info("completion context", {
4858
+ log6.info("completion context", {
4696
4859
  context
4697
4860
  }, {
4698
4861
  F: __dxlog_file10,
@@ -4716,7 +4879,7 @@ var mention = ({ onSearch }) => {
4716
4879
  };
4717
4880
 
4718
4881
  // packages/ui/react-ui-editor/src/extensions/modes.ts
4719
- import { keymap as keymap8 } from "@codemirror/view";
4882
+ import { keymap as keymap9 } from "@codemirror/view";
4720
4883
  import { vim } from "@replit/codemirror-vim";
4721
4884
  import { vscodeKeymap } from "@replit/codemirror-vscode-keymap";
4722
4885
  var focusEvent = "focus.container";
@@ -4738,7 +4901,7 @@ var InputModeExtensions = {
4738
4901
  editorInputMode.of({
4739
4902
  type: "vscode"
4740
4903
  }),
4741
- keymap8.of(vscodeKeymap)
4904
+ keymap9.of(vscodeKeymap)
4742
4905
  ],
4743
4906
  vim: [
4744
4907
  // https://github.com/replit/codemirror-vim
@@ -4747,7 +4910,7 @@ var InputModeExtensions = {
4747
4910
  type: "vim",
4748
4911
  noTabster: true
4749
4912
  }),
4750
- keymap8.of([
4913
+ keymap9.of([
4751
4914
  {
4752
4915
  key: "Alt-Escape",
4753
4916
  run: (view) => {
@@ -4762,7 +4925,7 @@ var InputModeExtensions = {
4762
4925
  };
4763
4926
 
4764
4927
  // packages/ui/react-ui-editor/src/extensions/typewriter.ts
4765
- import { keymap as keymap9 } from "@codemirror/view";
4928
+ import { keymap as keymap10 } from "@codemirror/view";
4766
4929
  var defaultItems = [
4767
4930
  "hello world!",
4768
4931
  "this is a test.",
@@ -4772,7 +4935,7 @@ var typewriter = ({ delay = 75, items = defaultItems } = {}) => {
4772
4935
  let t;
4773
4936
  let idx = 0;
4774
4937
  return [
4775
- keymap9.of([
4938
+ keymap10.of([
4776
4939
  {
4777
4940
  // Reset.
4778
4941
  key: "alt-meta-'",
@@ -4830,10 +4993,10 @@ var ToolbarSeparator = () => /* @__PURE__ */ React3.createElement("div", {
4830
4993
  className: "grow"
4831
4994
  });
4832
4995
  var [ToolbarContextProvider, useToolbarContext] = createContext("Toolbar");
4833
- var ToolbarRoot = ({ children, onAction, classNames, state: state2 }) => {
4996
+ var ToolbarRoot = ({ children, onAction, classNames, state }) => {
4834
4997
  return /* @__PURE__ */ React3.createElement(ToolbarContextProvider, {
4835
4998
  onAction,
4836
- state: state2
4999
+ state
4837
5000
  }, /* @__PURE__ */ React3.createElement(ElevationProvider, {
4838
5001
  elevation: "chrome"
4839
5002
  }, /* @__PURE__ */ React3.createElement(NaturalToolbar.Root, {
@@ -4883,8 +5046,8 @@ var HeadingIcons = {
4883
5046
  };
4884
5047
  var MarkdownHeading = () => {
4885
5048
  const { t } = useTranslation(translationKey);
4886
- const { onAction, state: state2 } = useToolbarContext("MarkdownFormatting");
4887
- const blockType = state2 ? state2.blockType : "paragraph";
5049
+ const { onAction, state } = useToolbarContext("MarkdownFormatting");
5050
+ const blockType = state ? state.blockType : "paragraph";
4888
5051
  const header = blockType && /heading(\d)/.exec(blockType);
4889
5052
  const value = header ? header[1] : blockType === "paragraph" || !blockType ? "0" : void 0;
4890
5053
  const HeadingIcon = HeadingIcons[value ?? "0"];
@@ -4948,43 +5111,43 @@ var markdownStyles = [
4948
5111
  {
4949
5112
  type: "strong",
4950
5113
  Icon: TextB,
4951
- getState: (state2) => !!state2?.strong
5114
+ getState: (state) => !!state?.strong
4952
5115
  },
4953
5116
  {
4954
5117
  type: "emphasis",
4955
5118
  Icon: TextItalic,
4956
- getState: (state2) => !!state2?.emphasis
5119
+ getState: (state) => !!state?.emphasis
4957
5120
  },
4958
5121
  {
4959
5122
  type: "strikethrough",
4960
5123
  Icon: TextStrikethrough,
4961
- getState: (state2) => !!state2?.strikethrough
5124
+ getState: (state) => !!state?.strikethrough
4962
5125
  },
4963
5126
  {
4964
5127
  type: "code",
4965
5128
  Icon: Code,
4966
- getState: (state2) => !!state2?.code
5129
+ getState: (state) => !!state?.code
4967
5130
  },
4968
5131
  {
4969
5132
  type: "link",
4970
5133
  Icon: Link,
4971
- getState: (state2) => !!state2?.link
5134
+ getState: (state) => !!state?.link
4972
5135
  }
4973
5136
  ];
4974
5137
  var MarkdownStyles = () => {
4975
- const { onAction, state: state2 } = useToolbarContext("MarkdownStyles");
5138
+ const { onAction, state } = useToolbarContext("MarkdownStyles");
4976
5139
  const { t } = useTranslation(translationKey);
4977
5140
  return /* @__PURE__ */ React3.createElement(NaturalToolbar.ToggleGroup, {
4978
5141
  type: "multiple",
4979
- value: markdownStyles.filter(({ getState }) => state2 && getState(state2)).map(({ type }) => type)
5142
+ value: markdownStyles.filter(({ getState }) => state && getState(state)).map(({ type }) => type)
4980
5143
  }, markdownStyles.map(({ type, getState, Icon: Icon2 }) => /* @__PURE__ */ React3.createElement(ToolbarToggleButton, {
4981
5144
  key: type,
4982
5145
  value: type,
4983
5146
  Icon: Icon2,
4984
- disabled: state2?.blockType === "codeblock",
4985
- onClick: state2 ? () => onAction?.({
5147
+ disabled: state?.blockType === "codeblock",
5148
+ onClick: state ? () => onAction?.({
4986
5149
  type,
4987
- data: !getState(state2)
5150
+ data: !getState(state)
4988
5151
  }) : void 0
4989
5152
  }, t(`${type} label`))));
4990
5153
  };
@@ -4992,32 +5155,32 @@ var markdownLists = [
4992
5155
  {
4993
5156
  type: "list-bullet",
4994
5157
  Icon: ListBullets,
4995
- getState: (state2) => state2.listStyle === "bullet"
5158
+ getState: (state) => state.listStyle === "bullet"
4996
5159
  },
4997
5160
  {
4998
5161
  type: "list-ordered",
4999
5162
  Icon: ListNumbers,
5000
- getState: (state2) => state2.listStyle === "ordered"
5163
+ getState: (state) => state.listStyle === "ordered"
5001
5164
  },
5002
5165
  {
5003
5166
  type: "list-task",
5004
5167
  Icon: ListChecks,
5005
- getState: (state2) => state2.listStyle === "task"
5168
+ getState: (state) => state.listStyle === "task"
5006
5169
  }
5007
5170
  ];
5008
5171
  var MarkdownLists = () => {
5009
- const { onAction, state: state2 } = useToolbarContext("MarkdownStyles");
5172
+ const { onAction, state } = useToolbarContext("MarkdownStyles");
5010
5173
  const { t } = useTranslation(translationKey);
5011
5174
  return /* @__PURE__ */ React3.createElement(NaturalToolbar.ToggleGroup, {
5012
5175
  type: "single",
5013
- value: state2?.listStyle ? `list-${state2.listStyle}` : ""
5176
+ value: state?.listStyle ? `list-${state.listStyle}` : ""
5014
5177
  }, markdownLists.map(({ type, getState, Icon: Icon2 }) => /* @__PURE__ */ React3.createElement(ToolbarToggleButton, {
5015
5178
  key: type,
5016
5179
  value: type,
5017
5180
  Icon: Icon2,
5018
- onClick: state2 ? () => onAction?.({
5181
+ onClick: state ? () => onAction?.({
5019
5182
  type,
5020
- data: !getState(state2)
5183
+ data: !getState(state)
5021
5184
  }) : void 0
5022
5185
  }, t(`${type} label`))));
5023
5186
  };
@@ -5025,24 +5188,24 @@ var markdownBlocks = [
5025
5188
  {
5026
5189
  type: "blockquote",
5027
5190
  Icon: Quotes,
5028
- getState: (state2) => !!state2?.blockQuote
5191
+ getState: (state) => !!state?.blockQuote
5029
5192
  },
5030
5193
  {
5031
5194
  type: "codeblock",
5032
5195
  Icon: CodeBlock,
5033
- getState: (state2) => state2.blockType === "codeblock"
5196
+ getState: (state) => state.blockType === "codeblock"
5034
5197
  },
5035
5198
  {
5036
5199
  type: "table",
5037
5200
  Icon: Table2,
5038
- getState: (state2) => state2.blockType === "tablecell",
5039
- disabled: (state2) => !state2.blankLine
5201
+ getState: (state) => state.blockType === "tablecell",
5202
+ disabled: (state) => !state.blankLine
5040
5203
  }
5041
5204
  ];
5042
5205
  var MarkdownBlocks = () => {
5043
- const { onAction, state: state2 } = useToolbarContext("MarkdownStyles");
5206
+ const { onAction, state } = useToolbarContext("MarkdownStyles");
5044
5207
  const { t } = useTranslation(translationKey);
5045
- const value = markdownBlocks.find(({ getState }) => state2 && getState(state2));
5208
+ const value = markdownBlocks.find(({ getState }) => state && getState(state));
5046
5209
  return /* @__PURE__ */ React3.createElement(NaturalToolbar.ToggleGroup, {
5047
5210
  type: "single",
5048
5211
  value: value?.type ?? ""
@@ -5050,10 +5213,10 @@ var MarkdownBlocks = () => {
5050
5213
  key: type,
5051
5214
  value: type,
5052
5215
  Icon: Icon2,
5053
- disabled: !state2 || disabled?.(state2),
5054
- onClick: state2 ? () => onAction?.({
5216
+ disabled: !state || disabled?.(state),
5217
+ onClick: state ? () => onAction?.({
5055
5218
  type,
5056
- data: !getState(state2)
5219
+ data: !getState(state)
5057
5220
  }) : void 0
5058
5221
  }, t(`${type} label`))));
5059
5222
  };
@@ -5166,12 +5329,12 @@ var MarkdownView = ({ mode }) => {
5166
5329
  })), /* @__PURE__ */ React3.createElement(DropdownMenu.Arrow, null)))), /* @__PURE__ */ React3.createElement(Tooltip.Portal, null, /* @__PURE__ */ React3.createElement(Tooltip.Content, tooltipProps, t("view mode label"), /* @__PURE__ */ React3.createElement(Tooltip.Arrow, null))));
5167
5330
  };
5168
5331
  var MarkdownActions = () => {
5169
- const { onAction, state: state2 } = useToolbarContext("MarkdownActions");
5332
+ const { onAction, state } = useToolbarContext("MarkdownActions");
5170
5333
  const { t } = useTranslation(translationKey);
5171
5334
  let commentToolTipKey = "comment label";
5172
- if (state2?.comment) {
5335
+ if (state?.comment) {
5173
5336
  commentToolTipKey = "selection overlaps existing comment label";
5174
- } else if (state2?.selection === false) {
5337
+ } else if (state?.selection === false) {
5175
5338
  commentToolTipKey = "select text to comment label";
5176
5339
  }
5177
5340
  return /* @__PURE__ */ React3.createElement(React3.Fragment, null, /* @__PURE__ */ React3.createElement(ToolbarButton, {
@@ -5187,7 +5350,7 @@ var MarkdownActions = () => {
5187
5350
  onClick: () => onAction?.({
5188
5351
  type: "comment"
5189
5352
  }),
5190
- disabled: !state2 || state2.comment || !state2.selection
5353
+ disabled: !state || state.comment || !state.selection
5191
5354
  }, t(commentToolTipKey)));
5192
5355
  };
5193
5356
  var Toolbar = {
@@ -5201,20 +5364,20 @@ var Toolbar = {
5201
5364
  };
5202
5365
 
5203
5366
  // packages/ui/react-ui-editor/src/defaults.ts
5204
- import { EditorView as EditorView17 } from "@codemirror/view";
5367
+ import { EditorView as EditorView19 } from "@codemirror/view";
5205
5368
  import { mx as mx3 } from "@dxos/react-ui-theme";
5206
5369
  var margin = "!mt-[1rem]";
5207
5370
  var editorContent = mx3(margin, "!mli-auto w-full max-w-[min(50rem,100%-2rem)]");
5208
5371
  var editorFullWidth = mx3(margin);
5209
5372
  var editorWithToolbarLayout = "grid grid-cols-1 grid-rows-[min-content_1fr] data-[toolbar=disabled]:grid-rows-[1fr] justify-center content-start overflow-hidden";
5210
- var editorGutter = EditorView17.theme({
5373
+ var editorGutter = EditorView19.theme({
5211
5374
  // Match margin from content.
5212
5375
  ".cm-gutters": {
5213
5376
  marginTop: "16px",
5214
5377
  paddingRight: "1rem"
5215
5378
  }
5216
5379
  });
5217
- var editorMonospace = EditorView17.theme({
5380
+ var editorMonospace = EditorView19.theme({
5218
5381
  ".cm-content": {
5219
5382
  fontFamily: fontMono
5220
5383
  }
@@ -5227,11 +5390,11 @@ var useActionHandler = (view) => {
5227
5390
 
5228
5391
  // packages/ui/react-ui-editor/src/hooks/useTextEditor.ts
5229
5392
  import { EditorState as EditorState2 } from "@codemirror/state";
5230
- import { EditorView as EditorView18 } from "@codemirror/view";
5393
+ import { EditorView as EditorView20 } from "@codemirror/view";
5231
5394
  import { useFocusableGroup } from "@fluentui/react-tabster";
5232
5395
  import { useCallback, useEffect as useEffect3, useMemo as useMemo3, useRef as useRef2, useState as useState4 } from "react";
5233
- import { log as log8 } from "@dxos/log";
5234
- import { getProviderValue, isNotFalsy as isNotFalsy3 } from "@dxos/util";
5396
+ import { log as log7 } from "@dxos/log";
5397
+ import { getProviderValue, isNotFalsy as isNotFalsy4 } from "@dxos/util";
5235
5398
  var __dxlog_file11 = "/home/runner/work/dxos/dxos/packages/ui/react-ui-editor/src/hooks/useTextEditor.ts";
5236
5399
  var instanceCount = 0;
5237
5400
  var useTextEditor = (props = {}, deps = []) => {
@@ -5242,13 +5405,13 @@ var useTextEditor = (props = {}, deps = []) => {
5242
5405
  useEffect3(() => {
5243
5406
  let view2;
5244
5407
  if (parentRef.current) {
5245
- log8("create", {
5408
+ log7("create", {
5246
5409
  id,
5247
5410
  instanceId,
5248
5411
  doc: initialValue?.length ?? 0
5249
5412
  }, {
5250
5413
  F: __dxlog_file11,
5251
- L: 76,
5414
+ L: 75,
5252
5415
  S: void 0,
5253
5416
  C: (f, a) => f(...a)
5254
5417
  });
@@ -5264,27 +5427,27 @@ var useTextEditor = (props = {}, deps = []) => {
5264
5427
  anchor
5265
5428
  };
5266
5429
  }
5267
- const state2 = EditorState2.create({
5430
+ const state = EditorState2.create({
5268
5431
  doc: initialValue,
5269
5432
  // selection: initialSelection,
5270
5433
  extensions: [
5271
5434
  id && documentId.of(id),
5272
5435
  extensions,
5273
5436
  // NOTE: This doesn't catch errors in keymap functions.
5274
- EditorView18.exceptionSink.of((err) => {
5275
- log8.catch(err, void 0, {
5437
+ EditorView20.exceptionSink.of((err) => {
5438
+ log7.catch(err, void 0, {
5276
5439
  F: __dxlog_file11,
5277
- L: 98,
5440
+ L: 97,
5278
5441
  S: void 0,
5279
5442
  C: (f, a) => f(...a)
5280
5443
  });
5281
5444
  })
5282
- ].filter(isNotFalsy3)
5445
+ ].filter(isNotFalsy4)
5283
5446
  });
5284
- view2 = new EditorView18({
5447
+ view2 = new EditorView20({
5285
5448
  parent: parentRef.current,
5286
- state: state2,
5287
- scrollTo: scrollTo ? EditorView18.scrollIntoView(scrollTo, {
5449
+ state,
5450
+ scrollTo: scrollTo ? EditorView20.scrollIntoView(scrollTo, {
5288
5451
  yMargin: 96
5289
5452
  }) : void 0,
5290
5453
  dispatchTransactions: debug ? debugDispatcher : void 0
@@ -5302,11 +5465,11 @@ var useTextEditor = (props = {}, deps = []) => {
5302
5465
  setView(view2);
5303
5466
  }
5304
5467
  return () => {
5305
- log8("destroy", {
5468
+ log7("destroy", {
5306
5469
  id
5307
5470
  }, {
5308
5471
  F: __dxlog_file11,
5309
- L: 135,
5472
+ L: 134,
5310
5473
  S: void 0,
5311
5474
  C: (f, a) => f(...a)
5312
5475
  });
@@ -5320,19 +5483,19 @@ var useTextEditor = (props = {}, deps = []) => {
5320
5483
  }
5321
5484
  if (scrollTo || selection) {
5322
5485
  if (selection && selection.anchor > view.state.doc.length) {
5323
- log8.warn("invalid selection", {
5486
+ log7.warn("invalid selection", {
5324
5487
  length: view.state.doc.length,
5325
5488
  scrollTo,
5326
5489
  selection
5327
5490
  }, {
5328
5491
  F: __dxlog_file11,
5329
- L: 149,
5492
+ L: 148,
5330
5493
  S: void 0,
5331
5494
  C: (f, a) => f(...a)
5332
5495
  });
5333
5496
  return;
5334
5497
  }
5335
- view.dispatch(createEditorStateTransaction(view.state, {
5498
+ view.dispatch(createEditorStateTransaction({
5336
5499
  scrollTo,
5337
5500
  selection
5338
5501
  }));
@@ -5401,6 +5564,7 @@ export {
5401
5564
  awarenessProvider,
5402
5565
  blast,
5403
5566
  callbackWrapper,
5567
+ clientRectsFor,
5404
5568
  command,
5405
5569
  comments,
5406
5570
  commentsState,
@@ -5408,7 +5572,9 @@ export {
5408
5572
  createBasicExtensions,
5409
5573
  createComment,
5410
5574
  createDataExtensions,
5575
+ createEditorStateStore,
5411
5576
  createEditorStateTransaction,
5577
+ createElement,
5412
5578
  createExternalCommentSync,
5413
5579
  createMarkdownExtensions,
5414
5580
  createThemeExtensions,
@@ -5425,23 +5591,25 @@ export {
5425
5591
  editorInputMode,
5426
5592
  editorMonospace,
5427
5593
  editorWithToolbarLayout,
5594
+ flattenRect,
5595
+ focus,
5428
5596
  focusEvent,
5597
+ focusField,
5429
5598
  folding,
5430
5599
  formattingEquals,
5431
5600
  formattingKeymap,
5432
5601
  getFormatting,
5433
5602
  image,
5434
- imageUpload,
5435
5603
  insertTable,
5436
- keymap10 as keymap,
5604
+ keymap11 as keymap,
5437
5605
  linkTooltip,
5438
5606
  listener,
5439
- localStorageStateStoreAdapter,
5440
5607
  logChanges,
5441
5608
  markdownHighlightStyle,
5442
5609
  markdownTags,
5443
5610
  markdownTagsExtensions,
5444
5611
  mention,
5612
+ overlap,
5445
5613
  preventNewline,
5446
5614
  processAction,
5447
5615
  removeBlockquote,
@@ -5449,17 +5617,19 @@ export {
5449
5617
  removeLink,
5450
5618
  removeList,
5451
5619
  removeStyle,
5620
+ renderRoot,
5452
5621
  scrollThreadIntoView,
5453
5622
  selectionOverlapsComment,
5623
+ selectionState,
5454
5624
  setBlockquote,
5455
5625
  setComments,
5456
5626
  setHeading,
5457
5627
  setSelection,
5458
5628
  setStyle,
5459
5629
  singleValueFacet,
5460
- state,
5461
5630
  table,
5462
5631
  tags2 as tags,
5632
+ textRange,
5463
5633
  toggleBlockquote,
5464
5634
  toggleCodeblock,
5465
5635
  toggleEmphasis,
@@ -5476,6 +5646,7 @@ export {
5476
5646
  useComments,
5477
5647
  useFormattingState,
5478
5648
  useTextEditor,
5479
- useToolbarContext
5649
+ useToolbarContext,
5650
+ wrapWithCatch
5480
5651
  };
5481
5652
  //# sourceMappingURL=index.mjs.map